]> git.sesse.net Git - vlc/blob - modules/gui/macosx/wizard.m
FSF address change.
[vlc] / modules / gui / macosx / wizard.m
1 /*****************************************************************************
2  * wizard.m: MacOS X Streaming Wizard
3  *****************************************************************************
4  * Copyright (C) 2005 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Felix Kühne <fkuehne@users.sf.net>
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24
25 /*****************************************************************************
26  * Note: this code is partially based upon ../wxwidgets/wizard.cpp and
27  *         ../wxwidgets/streamdata.h; both written by Clément Stenac.
28  *****************************************************************************/
29
30
31 /*****************************************************************************
32  * Preamble
33  *****************************************************************************/
34 #import "wizard.h"
35 #import "intf.h"
36 #import "network.h"
37 #import "playlist.h"
38
39 /*****************************************************************************
40  * VLCWizard implementation
41  *****************************************************************************/
42
43 @implementation VLCWizard
44
45 static VLCWizard *_o_sharedInstance = nil;
46
47 + (VLCWizard *)sharedInstance
48 {
49     return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
50 }
51
52 - (id)init
53 {
54     if (_o_sharedInstance) {
55         [self dealloc];
56     } else {
57         _o_sharedInstance = [super init];
58     }
59
60     return _o_sharedInstance;
61 }
62
63 - (void)dealloc
64 {
65     [o_userSelections release];
66     [o_videoCodecs release];
67     [o_audioCodecs release];
68     [o_encapFormats release];
69     [super dealloc];
70 }
71
72 - (void)awakeFromNib
73 {
74     /* some minor cleanup */
75     [o_t2_tbl_plst setEnabled:NO];
76     [o_wizardhelp_window setExcludedFromWindowsMenu:YES];
77     o_userSelections = [[NSMutableDictionary alloc] init];
78     [o_btn_backward setEnabled:NO];
79
80     /* add audio-bitrates for transcoding */
81     NSArray * audioBitratesArray;
82     audioBitratesArray = [NSArray arrayWithObjects: @"512", @"256", @"192", \
83         @"128", @"64", @"32", @"16", nil ];
84     [o_t4_pop_audioBitrate removeAllItems];
85     [o_t4_pop_audioBitrate addItemsWithTitles: audioBitratesArray];
86     [o_t4_pop_audioBitrate selectItemWithTitle: @"192"];
87
88     /* add video-bitrates for transcoding */
89     NSArray * videoBitratesArray;
90     videoBitratesArray = [NSArray arrayWithObjects: @"3072", @"2048", @"1024", \
91         @"768", @"512", @"256", @"192", @"128", @"64", @"32", @"16", nil ];
92     [o_t4_pop_videoBitrate removeAllItems];
93     [o_t4_pop_videoBitrate addItemsWithTitles: videoBitratesArray];
94     [o_t4_pop_videoBitrate selectItemWithTitle: @"1024"];
95
96     /* fill 2 global arrays with arrays containing all codec-related information
97      * - one array per codec named by its short name to define the encap-compability,
98      *     cmd-names, real names, more info in the order: realName, shortName,
99      *     moreInfo, encaps */
100     NSArray * o_mp1v;
101     NSArray * o_mp2v;
102     NSArray * o_mp4v;
103     NSArray * o_div1;
104     NSArray * o_div2;
105     NSArray * o_div3;
106     NSArray * o_h263;
107     NSArray * o_h264;
108     NSArray * o_wmv1;
109     NSArray * o_wmv2;
110     NSArray * o_mjpg;
111     NSArray * o_theo;
112     NSArray * o_dummyVid;
113     o_mp1v = [NSArray arrayWithObjects: @"MPEG-1 Video", @"mp1v", \
114         _NS("MPEG-1 Video codec (usable with MPEG PS, MPEG TS, MPEG1, OGG " \
115         "and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_OGG", @"MUX_RAW", \
116         @"NO", @"NO", @"NO", @"NO", nil];
117     o_mp2v = [NSArray arrayWithObjects: @"MPEG-2 Video", @"mp2v", \
118         _NS("MPEG-2 Video codec (usable with MPEG PS, MPEG TS, MPEG1, OGG " \
119         "and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_OGG", @"MUX_RAW", \
120         @"NO", @"NO", @"NO", @"NO", nil];
121     o_mp4v = [NSArray arrayWithObjects: @"MPEG-4 Video", @"mp4v", \
122         _NS("MPEG-4 Video codec (useable with MPEG PS, MPEG TS, MPEG1, ASF, " \
123         "MP4, OGG and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", \
124         @"MUX_MP4", @"MUX_OGG", @"MUX_RAW", @"NO", @"NO", nil];
125     o_div1 = [NSArray arrayWithObjects: @"DIVX 1", @"DIV1", \
126         _NS("DivX first version (useable with MPEG TS, MPEG1, ASF and OGG)"), \
127         @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", @"NO", @"NO", @"NO", \
128         @"NO", @"NO", nil];
129     o_div2 = [NSArray arrayWithObjects: @"DIVX 2", @"DIV2", \
130         _NS("DivX second version (useable with MPEG TS, MPEG1, ASF and OGG)"), \
131         @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", @"NO", @"NO", @"NO", \
132         @"NO", @"NO", nil];
133     o_div3 = [NSArray arrayWithObjects: @"DIVX 3", @"DIV3", \
134         _NS("DivX third version (useable with MPEG TS, MPEG1, ASF and OGG)"), \
135         @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", @"NO", @"NO", @"NO", \
136         @"NO", @"NO", nil];
137     o_h263 = [NSArray arrayWithObjects: @"H.263", @"h263", \
138         _NS("H263 is a video codec optimized for videoconference " \
139         "(low rates, useable with MPEG TS)"), @"MUX_TS", @"NO", @"NO", @"NO", \
140         @"NO", @"NO", @"NO", @"NO", @"NO", nil];
141     o_h264 = [NSArray arrayWithObjects: @"H.264", @"h264", \
142         _NS("H264 is a new video codec (useable with MPEG TS and MP4)"), \
143         @"MUX_TS", @"MUX_MP4", @"NO", @"NO", @"NO", @"NO", @"NO", @"NO", \
144         @"NO", nil];
145     o_wmv1 = [NSArray arrayWithObjects: @"WMV 1", @"WMV1", \
146         _NS("WMV (Windows Media Video) 1 (useable with MPEG TS, MPEG1, ASF and " \
147         "OGG)"), @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", @"NO", @"NO", \
148         @"NO", @"NO", @"NO", nil];
149     o_wmv2 = [NSArray arrayWithObjects: @"WMV 2", @"WMV2", \
150         _NS("WMV (Windows Media Video) 2 (useable with MPEG TS, MPEG1, ASF and " \
151         "OGG)"), @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", @"NO", @"NO", \
152         @"NO", @"NO", @"NO", nil];
153     o_mjpg = [NSArray arrayWithObjects: @"MJPEG", @"MJPG", \
154         _NS("MJPEG consists of a series of JPEG pictures (useable with MPEG TS," \
155         " MPEG1, ASF and OGG)"), @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", \
156         @"NO", @"NO", @"NO", @"NO", @"NO", nil];
157     o_theo = [NSArray arrayWithObjects: @"Theora", @"theo", \
158         _NS("Theora is a free general-purpose codec (useable with MPEG TS)"), \
159         @"MUX_TS", @"NO", @"NO", @"NO", @"NO", @"NO", @"NO", @"NO", @"NO", nil];
160     o_dummyVid = [NSArray arrayWithObjects: @"Dummy", @"dummy", \
161         _NS("Dummy codec (do not transcode, useable with all encapsulation " \
162         "formats)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_MP4", \
163         @"MUX_OGG", @"MUX_WAV", @"MUX_RAW", @"MUX_MOV", nil];
164     o_videoCodecs = [[NSArray alloc] initWithObjects: o_mp1v, o_mp2v, o_mp4v, \
165         o_div1, o_div2, o_div3, o_h263, o_h264, o_wmv1, o_wmv2, o_mjpg, o_theo, \
166         o_dummyVid, nil];
167     
168
169     NSArray * o_mpga;
170     NSArray * o_mp3;
171     NSArray * o_mp4a;
172     NSArray * o_a52;
173     NSArray * o_vorb;
174     NSArray * o_flac;
175     NSArray * o_spx;
176     NSArray * o_s16l;
177     NSArray * o_fl32;
178     NSArray * o_dummyAud;
179     o_mpga = [NSArray arrayWithObjects: @"MPEG Audio", @"mpga", \
180         _NS("The standard MPEG audio (1/2) format (useable with MPEG PS, MPEG TS, " \
181         "MPEG1, ASF, OGG and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", \
182         @"MUX_ASF", @"MUX_OGG", @"MUX_RAW", @"-1", @"-1", @"-1", nil];
183     o_mp3 = [NSArray arrayWithObjects: @"MP3", @"mp3", \
184         _NS("MPEG Audio Layer 3 (useable with MPEG PS, MPEG TS, MPEG1, ASF, OGG " \
185         "and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", \
186         @"MUX_RAW", @"-1", @"-1", @"-1", nil];
187     o_mp4a = [NSArray arrayWithObjects: @"MPEG 4 Audio", @"mp4a", \
188         _NS("Audio format for MPEG4 (useable with MPEG TS and MPEG4)"), @"MUX_TS", \
189         @"MUX_MP4", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", nil];
190     o_a52 = [NSArray arrayWithObjects: @"A/52", @"a52", 
191         _NS("DVD audio format (useable with MPEG PS, MPEG TS, MPEG1, ASF, OGG " \
192         "and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", \
193         @"MUX_RAW", @"-1", @"-1", @"-1", nil];
194     o_vorb = [NSArray arrayWithObjects: @"Vorbis", @"vorb", \
195         _NS("Vorbis is a free audio codec (useable with OGG)"), @"MUX_OGG", \
196         @"-1",  @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", nil];
197     o_flac = [NSArray arrayWithObjects: @"FLAC", @"flac", \
198         _NS("FLAC is a lossless audio codec (useable with OGG and RAW)"), \
199         @"MUX_OGG", @"MUX_RAW", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", \
200         @"-1", nil];
201     o_spx = [NSArray arrayWithObjects: @"Speex", @"spx", \
202         _NS("A free audio codec dedicated to compression of voice (useable " \
203         "with OGG)"), @"MUX_OGG", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", \
204         @"-1", @"-1", nil];
205     o_s16l = [NSArray arrayWithObjects: @"Uncompressed, integer", @"s16l", \
206         _NS("Uncompressed audio samples (useable with WAV)"), @"MUX_WAV", \
207         @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", nil];
208     o_fl32 = [NSArray arrayWithObjects: @"Uncompressed, floating", @"fl32", \
209         _NS("Uncompressed audio samples (useable with WAV)"), @"MUX_WAV", \
210         @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", nil];
211     o_dummyAud = [NSArray arrayWithObjects: @"Dummy", @"dummy", \
212         _NS("Dummy codec (do not transcode, useable with all encapsulation " \
213         "formats)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_MP4", \
214         @"MUX_OGG", @"MUX_RAW", @"MUX_MOV", @"MUX_WAV", nil];
215     o_audioCodecs = [[NSArray alloc] initWithObjects: o_mpga, o_mp3, o_mp4a, \
216         o_a52, o_vorb, o_flac, o_spx, o_s16l, o_fl32, o_dummyAud, nil];
217
218
219     /* fill another global array with all information about the encap-formats
220      * note that the order of the formats inside the g. array is the same as on
221      * the encap-tab */
222     NSArray * o_ps;
223     NSArray * o_ts;
224     NSArray * o_mpeg;
225     NSArray * o_ogg;
226     NSArray * o_raw;
227     NSArray * o_asf;
228     NSArray * o_avi;
229     NSArray * o_mp4;
230     NSArray * o_mov;
231     NSArray * o_wav;
232     NSArray * o_asfh;
233     o_ps = [NSArray arrayWithObjects: @"ps", @"MPEG PS", \
234         _NS("MPEG Program Stream"), @"mpg", nil];
235     o_ts = [NSArray arrayWithObjects: @"ts", @"MPEG TS", \
236         _NS("MPEG Transport Stream"), nil];
237     o_mpeg = [NSArray arrayWithObjects: @"ps", @"MPEG 1", \
238         _NS("MPEG 1 Format"), @"mpg", nil];
239     o_ogg = [NSArray arrayWithObjects: @"ogg", @"OGG", @"OGG", nil];
240     o_raw = [NSArray arrayWithObjects: @"raw", @"RAW", @"RAW", nil];
241     o_asf = [NSArray arrayWithObjects: @"asf", @"ASF", @"ASF", nil];
242     o_avi = [NSArray arrayWithObjects: @"avi", @"AVI", @"AVI", nil];
243     o_mp4 = [NSArray arrayWithObjects: @"mp4", @"MP4", @"MPEG4", nil];
244     o_mov = [NSArray arrayWithObjects: @"mov", @"MOV", @"MOV", nil];
245     o_wav = [NSArray arrayWithObjects: @"wav", @"WAV", @"WAV", nil];
246     o_asfh = [NSArray arrayWithObjects: @"asfh", @"ASFH", @"ASFH", nil];
247     o_encapFormats = [[NSArray alloc] initWithObjects: o_ps, o_ts, o_mpeg, \
248         o_ogg, o_raw, o_asf, o_avi, o_mp4, o_mov, o_wav, o_asfh, nil];
249
250     /* yet another array on streaming methods including help texts */
251     NSArray * o_http;
252     NSArray * o_mms;
253     NSArray * o_udp_uni;
254     NSArray * o_udp_multi;
255     NSArray * o_rtp_uni;
256     NSArray * o_rtp_multi;
257     o_http = [NSArray arrayWithObjects: @"http", @"HTTP", _NS("Enter the local " \
258         "addresses you want to listen to. Do not enter anything if you want to " \
259         "listen to all adresses or if you don't understand. This is generally " \
260         "the best thing to do. Other computers can then access the stream at " \
261         "http://yourip:8080 by default.") , _NS("Use this to stream to several " \
262         "computers. This method is less efficient, as the server needs to send " \
263         "the stream several times."), nil];
264     o_mms = [NSArray arrayWithObjects: @"mmsh", @"MMS", _NS("Enter the local " \
265         "addresses you want to listen to. Do not enter anything if you want to " \
266         "listen to all adresses or if you don't understand. This is generally " \
267         "the best thing to do. Other computers can then access the stream at " \
268         "mms://yourip:8080 by default."), _NS("Use this to stream to several " \
269         "computers using the Microsoft MMS protocol. This protocol is used as " \
270         "transport method by many Microsoft's softwares. Note that only a " \
271         "small part of the MMS protocol is supported (MMS encapsulated in " \
272         "HTTP)." ), nil];
273     o_udp_uni = [NSArray arrayWithObjects: @"udp", @"UDP-Unicast", _NS("Enter " \
274         "the address of the computer to stream to."), _NS("Use this to stream " \
275         "to a single computer."), nil];
276     o_udp_multi = [NSArray arrayWithObjects: @"udp", @"UDP-Multicast", _NS("Enter " \
277         "the multicast address to stream to in this field. This must be an IP " \
278         "address between 224.0.0.0 and 239.255.255.255. For a private use, " \
279         "enter an address beginning with 239.255."), _NS("Use this to stream " \
280         "to a dynamic group of computers on a multicast-enabled network. This " \
281         "is the most efficient method to stream to several computers, but it " \
282         "does not work over Internet."), nil];
283     o_rtp_uni = [NSArray arrayWithObjects: @"rtp", @"RTP-Unicast", _NS("Enter the " \
284         "address of the computer to stream to.") , _NS("Use this to stream " \
285         "to a single computer."), nil];
286     o_rtp_multi = [NSArray arrayWithObjects: @"rtp", @"RTP-Multicast", _NS("Enter " \
287         "the multicast address to stream to in this field. This must be an IP " \
288         "address between 224.0.0.0 and 239.255.255.255. For a private use, " \
289         "enter an address beginning with 239.255."), _NS("Use this to stream " \
290         "to a dynamic group of computers on a multicast-enabled network. This " \
291         "is the most efficient method to stream to several computers, but it " \
292         "does not work over Internet."), nil];
293     o_strmgMthds = [[NSArray alloc] initWithObjects: o_http, o_mms, \
294         o_udp_uni, o_udp_multi, o_rtp_uni, o_rtp_multi, nil];
295 }
296
297 - (void)showWizard
298 {
299     /* just present the window to the user */
300     [o_tab_pageHolder selectFirstTabViewItem:self];
301
302     [o_wizard_window center];
303     [o_wizard_window displayIfNeeded];
304     [o_wizard_window makeKeyAndOrderFront:nil];
305 }
306
307 - (void)resetWizard
308 {
309     /* reset the wizard-window to its default values */
310
311     [o_userSelections removeAllObjects];
312     [o_t1_matrix_strmgOrTrnscd selectCellAtRow:0 column:0];
313     [[o_t1_matrix_strmgOrTrnscd cellAtRow:1 column:0] setState: NSOffState];
314     [o_btn_forward setTitle: _NS("Next")];
315
316     /* "Input" */
317     [o_t2_fld_pathToNewStrm setStringValue: @""];
318     [o_t2_ckb_enblPartExtrct setState: NSOffState];
319     [self t2_enableExtract:nil];
320     [o_t2_matrix_inputSourceType selectCellAtRow:0 column:0];
321     [[o_t2_matrix_inputSourceType cellAtRow:1 column:0] setState: NSOffState];
322     [o_t2_fld_pathToNewStrm setEnabled:YES];
323     [o_t2_btn_chooseFile setEnabled:YES];
324     [o_t2_tbl_plst setEnabled:NO];
325
326     /* "Streaming 1" */
327     [o_t3_fld_address setStringValue: @""];
328     [o_t3_matrix_stmgMhd selectCellAtRow:0 column:0];
329     [[o_t3_matrix_stmgMhd cellAtRow:0 column:1] setState: NSOffState];
330     [[o_t3_matrix_stmgMhd cellAtRow:1 column:1] setState: NSOffState];
331     [[o_t3_matrix_stmgMhd cellAtRow:1 column:2] setState: NSOffState];
332
333     /* "Transcode 1" */
334     [o_t4_ckb_audio setState: NSOffState];
335     [o_t4_ckb_video setState: NSOffState];
336     [self t4_enblVidTrnscd:nil];
337     [self t4_enblAudTrnscd:nil];
338
339     /* "Streaming 2" */
340     [o_t6_fld_ttl setStringValue: @"1"];
341     [o_t6_ckb_sap setState: NSOffState];
342     [self t6_enblSapAnnce:nil];
343
344     /* "Transcode 2" */
345     [o_t7_fld_filePath setStringValue: @""];
346 }
347
348 - (void)initStrings
349 {
350     /* localise all strings to the users lang */
351     /* method is called from intf.m (in method showWizard) */
352
353     /* general items */
354     [o_btn_backward setTitle: _NS("Back")];
355     [o_btn_cancel setTitle: _NS("Cancel")];
356     [o_btn_forward setTitle: _NS("Next")];
357     [o_wizard_window setTitle: _NS("Streaming/Transcoding Wizard")];
358
359     /* page one ("Hello") */
360     [o_t1_txt_title setStringValue: _NS("Streaming/Transcoding Wizard")];
361     [o_t1_txt_text setStringValue: _NS("This wizard helps you to stream, " \
362         "transcode or save a stream.")];
363     [o_t1_btn_mrInfo_strmg setTitle: _NS("More Info")];
364     [o_t1_btn_mrInfo_trnscd setTitle: _NS("More Info")];
365     [o_t1_txt_notice setStringValue: _NS("This wizard only gives access to " \
366         "a small subset of VLC's streaming and transcoding capabilities. " \
367         "Use the Open and Stream Output dialogs to get all of them.")];
368     [[o_t1_matrix_strmgOrTrnscd cellAtRow:0 column:0] setTitle: _NS("Stream " \
369         "to network")];
370     [[o_t1_matrix_strmgOrTrnscd cellAtRow:1 column:0] setTitle: _NS("" \
371         "Transcode/Save to file")];
372
373     /* page two ("Input") */
374     [o_t2_title setStringValue: _NS("Choose input")];
375     [o_t2_text setStringValue: _NS("Choose here your input stream.")];
376     [[o_t2_matrix_inputSourceType cellAtRow:0 column:0] setTitle:  \
377         _NS("Select a stream")];
378     [[o_t2_matrix_inputSourceType cellAtRow:1 column:0] setTitle: \
379         _NS("Existing playlist item")];
380     [o_t2_btn_chooseFile setTitle: _NS("Choose...")];
381     [[[o_t2_tbl_plst tableColumnWithIdentifier:@"1"] headerCell] \
382         setStringValue: _NS("Title")];
383     [[[o_t2_tbl_plst tableColumnWithIdentifier:@"2"] headerCell] \
384         setStringValue: _NS("Author")];
385     [o_t2_box_prtExtrct setTitle: _NS("Partial Extract")];
386     [o_t2_ckb_enblPartExtrct setTitle: _NS("Enable")];
387     [o_t2_ckb_enblPartExtrct setToolTip: _NS("Use this to read only a part of "\
388         "the stream. You must be able to control the incoming stream " \
389         "(for example, a file or a disc, but not an UDP network stream.) " \
390         "Enter the starting and ending times (in seconds).")];
391     [o_t2_txt_prtExtrctFrom setStringValue: _NS("From")];
392     [o_t2_txt_prtExtrctTo setStringValue: _NS("To")];
393
394     /* page three ("Streaming 1") */
395     [o_t3_txt_title setStringValue: _NS("Streaming")];
396     [o_t3_txt_text setStringValue: _NS("In this page, you will select how " \
397         "your input stream will be sent.")];
398     [o_t3_box_dest setTitle: _NS("Destination")];
399     [o_t3_box_strmgMthd setTitle: _NS("Streaming method")];
400     [o_t3_txt_destInfo setStringValue: _NS("Enter the address of the computer " \
401         "to stream to.")];
402     [[o_t3_matrix_stmgMhd cellAtRow:0 column:0] setTitle: _NS("UDP Unicast")];
403     [[o_t3_matrix_stmgMhd cellAtRow:0 column:1] setTitle: _NS("UDP Multicast")];
404     [o_t3_txt_strgMthdInfo setStringValue: _NS("Use this to stream to a single " \
405         "computer.")];
406
407     /* page four ("Transcode 1") */
408     [o_t4_title setStringValue: _NS("Transcode")];
409     [o_t4_text setStringValue: _NS("If you want to change the compression " \
410         "format of the audio or video tracks, fill in this page. (If you only " \
411         "want to change the container format, proceed to next page.)")];
412     [o_t4_box_audio setTitle: _NS("Audio")];
413     [o_t4_box_video setTitle: _NS("Video")];
414     [o_t4_ckb_audio setTitle: _NS("Transcode audio")];
415     [o_t4_ckb_video setTitle: _NS("Transcode video")];
416     [o_t4_txt_videoBitrate setStringValue: _NS("Bitrate (kb/s)")];
417     [o_t4_txt_videoCodec setStringValue: _NS("Codec")];
418     [o_t4_txt_hintAudio setStringValue: _NS("If your stream has audio and you " \
419         "want to transcode it, enable this.")];
420     [o_t4_txt_hintVideo setStringValue: _NS("If your stream has video and you " \
421         "want to transcode it, enable this.")];
422
423     /* page five ("Encap") */
424     [o_t5_title setStringValue: _NS("Encapsulation format")];
425     [o_t5_text setStringValue: _NS("In this page, you will select how the " \
426         "stream will be encapsulated. Depending on the choices you made, all " \
427                      "formats won't be available.")];
428
429     /* page six ("Streaming 2") */
430     [o_t6_title setStringValue: _NS("Additional streaming options")];
431     [o_t6_text setStringValue: _NS("In this page, you will define a few " \
432                               "additional parameters for your stream.")];
433     [o_t6_txt_ttl setStringValue: _NS("Time-To-Live (TTL)")];
434     [o_t6_btn_mrInfo_ttl setTitle: _NS("More Info")];
435     [o_t6_ckb_sap setTitle: _NS("SAP Announce")];
436     [o_t6_btn_mrInfo_sap setTitle: _NS("More Info")];
437     [o_t6_ckb_local setTitle: _NS("Local playback")];
438     [o_t6_btn_mrInfo_local setTitle: _NS("More Info")];
439
440     /* page seven ("Transcode 2") */
441     [o_t7_title setStringValue: _NS("Additional transcode options")];
442     [o_t7_text setStringValue: _NS("In this page, you will define a few " \
443                               "additional parameters for your transcoding.")];
444     [o_t7_txt_saveFileTo setStringValue: _NS("Select the file to save to")];
445     [o_t7_btn_chooseFile setTitle: _NS("Choose...")];
446     [o_t7_ckb_local setTitle: _NS("Local playback")];
447     [o_t7_btn_mrInfo_local setTitle: _NS("More Info")];
448
449     /* page eight ("Summary") */
450     [o_t8_txt_text setStringValue: _NS("This page lists all your selections. " \
451         "Click \"Finish\" to start your streaming or transcoding.")];
452     [o_t8_txt_title setStringValue: _NS("Summary")];
453     [o_t8_txt_destination setStringValue: [_NS("Destination") \
454         stringByAppendingString: @":"]];
455     [o_t8_txt_encapFormat setStringValue: [_NS("Encap. format") \
456         stringByAppendingString: @":"]];
457     [o_t8_txt_inputStream setStringValue: [_NS("Input stream") \
458         stringByAppendingString: @":"]];
459     [o_t8_txt_partExtract setStringValue: [_NS("Partial Extract") \
460         stringByAppendingString: @":"]];
461     [o_t8_txt_sap setStringValue: [_NS("SAP Announce") \
462         stringByAppendingString: @":"]];
463     [o_t8_txt_saveFileTo setStringValue: [_NS("Save file to") \
464         stringByAppendingString: @":"]];
465     [o_t8_txt_strmgMthd setStringValue: [_NS("Streaming method") \
466         stringByAppendingString: @":"]];
467     [o_t8_txt_trnscdAudio setStringValue: [_NS("Transcode audio") \
468         stringByAppendingString: @":"]];
469     [o_t8_txt_trnscdVideo setStringValue: [_NS("Transcode video") \
470         stringByAppendingString: @":"]];
471     [o_t8_txt_local setStringValue: [_NS("Local playback") \
472         stringByAppendingString: @":"]];
473
474     /* wizard help window */
475     [o_wh_btn_okay setTitle: _NS("OK")];
476 }
477
478 - (void)initWithExtractValuesFrom: (NSString *)from to: (NSString *)to \
479     ofItem: (NSString *)item
480 {
481     [self resetWizard];
482     msg_Dbg(VLCIntf, "wizard was reseted");
483     [o_userSelections setObject:@"trnscd" forKey:@"trnscdOrStrmg"];
484     [o_btn_backward setEnabled:YES];
485     [o_tab_pageHolder selectTabViewItemAtIndex:1];
486     [o_t2_fld_prtExtrctFrom setStringValue: from];
487     [o_t2_fld_prtExtrctTo setStringValue: to];
488     [o_t2_fld_pathToNewStrm setStringValue: item];
489     [o_t1_matrix_strmgOrTrnscd selectCellAtRow:1 column:0];
490     [[o_t1_matrix_strmgOrTrnscd cellAtRow:0 column:0] setState: NSOffState];
491     [o_t2_ckb_enblPartExtrct setState: NSOnState];
492     [self t2_enableExtract: nil];
493     msg_Dbg(VLCIntf, "wizard interface is set");
494     
495     [o_wizard_window center];
496     [o_wizard_window display];
497     [o_wizard_window makeKeyAndOrderFront:nil];
498     msg_Dbg(VLCIntf, "wizard window displayed");
499 }
500
501 - (IBAction)cancelRun:(id)sender
502 {
503     [o_wizard_window close];
504 }
505
506 - (id)getPlaylistWizard
507 {
508     return o_playlist_wizard;
509 }
510
511 - (IBAction)nextTab:(id)sender
512 {
513     if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: @"Hello"])
514     {
515         /* check whether the user wants to stream or just to transcode;
516          * store information for later usage */
517         NSString *o_mode;
518         o_mode = [[o_t1_matrix_strmgOrTrnscd selectedCell] title];
519         if( [o_mode isEqualToString: _NS("Stream to network")] )
520         {
521             [o_userSelections setObject:@"strmg" forKey:@"trnscdOrStrmg"];
522         }else{
523             [o_userSelections setObject:@"trnscd" forKey:@"trnscdOrStrmg"];
524         }
525         [o_btn_backward setEnabled:YES];
526         [o_tab_pageHolder selectTabViewItemAtIndex:1];
527
528         /* Fill the playlist with current playlist items */
529         [o_playlist_wizard reloadOutlineView];
530
531     }
532     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: @"Input"])
533     {
534         /* check whether partialExtract is enabled and store the values, if needed */
535         if ([o_t2_ckb_enblPartExtrct state] == NSOnState)
536         {
537             [o_userSelections setObject:@"YES" forKey:@"partExtract"];
538             [o_userSelections setObject:[o_t2_fld_prtExtrctFrom stringValue] \
539                 forKey:@"partExtractFrom"];
540             [o_userSelections setObject:[o_t2_fld_prtExtrctTo stringValue] \
541                 forKey:@"partExtractTo"];
542         }else{
543             [o_userSelections setObject:@"NO" forKey:@"partExtract"];
544         }
545
546         /* check whether we use an existing pl-item or add an new one;
547          * store the path or the index and set a flag.
548          * complain to the user if s/he didn't provide a path */
549         NSString *o_mode;
550         BOOL stop;
551         stop = NO;
552         o_mode = [[o_t2_matrix_inputSourceType selectedCell] title];
553         if( [o_mode isEqualToString: _NS("Select a stream")] )
554         {
555             [o_userSelections setObject:@"YES" forKey:@"newStrm"];
556             if ([[o_t2_fld_pathToNewStrm stringValue] isEqualToString: @""])
557             {
558                 /* set a flag that no file is selected */
559                 stop = YES;
560             }
561             else
562             {
563                 [o_userSelections setObject:[o_t2_fld_pathToNewStrm stringValue] \
564                     forKey:@"pathToStrm"];
565             }
566         }
567         else
568         {
569             if ([o_t2_tbl_plst selectedRow] != -1)
570             {
571                 playlist_item_t *p_item =
572                                     [o_playlist_wizard selectedPlaylistItem];
573                 if( p_item->i_children <= 0 )
574                 {
575                     [o_userSelections setObject: [NSString stringWithFormat:
576                         @"%s", p_item->input.psz_uri] forKey:@"pathToStrm"];
577                 }
578                 else
579                 stop = YES;
580             } else {
581                 /* set a flag that no item is selected */
582                 stop = YES;
583             }
584         }
585
586         /* show either "Streaming 1" or "Transcode 1" to the user */
587         if (stop == NO)
588         {
589             if ([[o_userSelections objectForKey:@"trnscdOrStrmg"] \
590                 isEqualToString:@"strmg"])
591             {
592                 /* we are streaming */
593                 [o_tab_pageHolder selectTabViewItemAtIndex:2];
594             }else{
595                 /* we are just transcoding */
596
597                 /* rebuild the menues for the codec-selections */
598                 [self rebuildCodecMenus];
599
600                 [o_tab_pageHolder selectTabViewItemAtIndex:3];
601             }
602         } else {
603             /* show a sheet that the user didn't select a file */
604             NSBeginInformationalAlertSheet(_NS("No input selected"), \
605                 _NS("OK"), @"", @"", o_wizard_window, nil, nil, nil, nil, \
606                 _NS("You have selected neither a new stream nor a valid " \
607                 "playlist item. VLC is unable to guess, which input you " \
608                 "want use.\n\nChoose one before going to the next page."));
609         }
610     }
611     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
612         @"Streaming 1"])
613     {
614         /* rebuild the menues for the codec-selections */
615         [self rebuildCodecMenus];
616         
617         /* check which streaming method is selected and store it */
618         int mode;
619         mode = [[o_t3_matrix_stmgMhd selectedCell] tag];
620         if( mode == 0 )
621         {
622             /* HTTP Streaming */
623             [o_userSelections setObject:@"0" forKey:@"stmgMhd"];
624
625             /* disable all codecs which don't support MPEG PS, MPEG TS, MPEG 1,
626              * OGG, RAW or ASF */
627             [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, integer"];
628             [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, floating"];
629             
630         } else if ( mode == 1 )
631         {
632             /* MMS Streaming */
633             [o_userSelections setObject:@"1" forKey:@"stmgMhd"];
634             
635             /* disable all codecs which don't support ASF / ASFH */
636             [o_t4_pop_audioCodec removeItemWithTitle:@"MPEG 4 Audio"];
637             [o_t4_pop_audioCodec removeItemWithTitle:@"Vorbis"];
638             [o_t4_pop_audioCodec removeItemWithTitle:@"FLAC"];
639             [o_t4_pop_audioCodec removeItemWithTitle:@"Speex"];
640             [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, integer"];
641             [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, floating"];
642             
643             [o_t4_pop_videoCodec removeItemWithTitle:@"MPEG-1 Video"];
644             [o_t4_pop_videoCodec removeItemWithTitle:@"MPEG-2 Video"];
645             [o_t4_pop_videoCodec removeItemWithTitle:@"H.263"];
646             [o_t4_pop_videoCodec removeItemWithTitle:@"H.264"];
647             [o_t4_pop_videoCodec removeItemWithTitle:@"MJPEG"];
648             [o_t4_pop_videoCodec removeItemWithTitle:@"Theora"];
649         } else {
650             /* RTP/UDP Unicast/Multicast Streaming */
651             
652             [o_userSelections setObject: [[NSNumber numberWithInt: mode] \
653                 stringValue] forKey:@"stmgMhd"];
654             
655             /* disable all codecs which don't support MPEG-TS */
656             [o_t4_pop_audioCodec removeItemWithTitle:@"Vorbis"];
657             [o_t4_pop_audioCodec removeItemWithTitle:@"FLAC"];
658             [o_t4_pop_audioCodec removeItemWithTitle:@"Speex"];
659             [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, integer"];
660             [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, floating"];
661         }
662
663         /* store the destination and check whether is it empty */
664         if([[o_userSelections objectForKey:@"stmgMhd"] intValue] >=2 )
665         {
666            /* empty field is valid for HTTP and MMS */
667             if( [[o_t3_fld_address stringValue] isEqualToString: @""] )
668             {
669                 /* complain to the user that "" is no valid dest. */
670                 NSBeginInformationalAlertSheet(_NS("No valid destination"), \
671                     _NS("OK"), @"", @"", o_wizard_window, nil, nil, nil, nil, \
672                     _NS("You need to enter a valid destination you want to "\
673                     "stream to. Enter either a Unicast-IP or a Multicast-IP." \
674                     "\n\nIf you don't know what this means, have a look at " \
675                     "the VLC Streaming HOWTO and the help texts in this " \
676                     "window."));
677             } else {
678                 /* FIXME: check whether the entered IP is really valid */
679                 [o_userSelections setObject:[o_t3_fld_address stringValue] \
680                     forKey:@"stmgDest"];
681                 /* let's go to the transcode-1-tab */
682                 [o_tab_pageHolder selectTabViewItemAtIndex:3];
683             }
684         } else {
685             [o_userSelections setObject:[o_t3_fld_address stringValue] \
686                 forKey:@"stmgDest"];
687             /* let's go to the transcode-1-tab */
688             [o_tab_pageHolder selectTabViewItemAtIndex:3];
689         }
690     }
691     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
692         @"Transcode 1"])
693     {
694         /* check whether the user wants to transcode the video-track and store 
695          * the related options */
696         if ([o_t4_ckb_video state] == NSOnState)
697         {
698             NSNumber * theNum;
699             theNum = [NSNumber numberWithInt:[o_t4_pop_videoCodec indexOfSelectedItem]];
700             [o_userSelections setObject:@"YES" forKey:@"trnscdVideo"];
701             [o_userSelections setObject:[o_t4_pop_videoBitrate titleOfSelectedItem] \
702                 forKey:@"trnscdVideoBitrate"];
703             [o_userSelections setObject:theNum forKey:@"trnscdVideoCodec"];
704         } else {
705             [o_userSelections setObject:@"NO" forKey:@"trnscdVideo"];
706         }
707
708         /* check whether the user wants to transcode the audio-track and store 
709          * the related options */
710         if ([o_t4_ckb_audio state] == NSOnState)
711         {
712             NSNumber * theNum;
713             theNum = [NSNumber numberWithInt:[o_t4_pop_audioCodec indexOfSelectedItem]];
714             [o_userSelections setObject:@"YES" forKey:@"trnscdAudio"];
715             [o_userSelections setObject:[o_t4_pop_audioBitrate titleOfSelectedItem] \
716                 forKey:@"trnscdAudioBitrate"];
717             [o_userSelections setObject:theNum forKey:@"trnscdAudioCodec"];
718         } else {
719             [o_userSelections setObject:@"NO" forKey:@"trnscdAudio"];
720         }
721
722         /* disable all encap-formats */
723         [[o_t5_matrix_encap cellAtRow:0 column:0] setEnabled:NO];
724         [[o_t5_matrix_encap cellAtRow:1 column:0] setEnabled:NO];
725         [[o_t5_matrix_encap cellAtRow:2 column:0] setEnabled:NO];
726         [[o_t5_matrix_encap cellAtRow:3 column:0] setEnabled:NO];
727         [[o_t5_matrix_encap cellAtRow:4 column:0] setEnabled:NO];
728         [[o_t5_matrix_encap cellAtRow:5 column:0] setEnabled:NO];
729         [[o_t5_matrix_encap cellAtRow:6 column:0] setEnabled:NO];
730         [[o_t5_matrix_encap cellAtRow:7 column:0] setEnabled:NO];
731         [[o_t5_matrix_encap cellAtRow:8 column:0] setEnabled:NO];
732         [[o_t5_matrix_encap cellAtRow:9 column:0] setEnabled:NO];
733         [[o_t5_matrix_encap cellAtRow:10 column:0] setEnabled:NO];
734
735         /* re-enable the encap-formats supported by the chosen codecs */
736         /* FIXME: the following is a really bad coding-style. feel free to mail
737             me ideas how to make this nicer, if you want to -- FK, 7/11/05 */
738
739         if ([[o_userSelections objectForKey:@"trnscdAudio"] isEqualTo: @"YES"])
740         {
741             if ([[o_userSelections objectForKey:@"trnscdVideo"] isEqualTo: @"YES"])
742             {
743                 /* we are transcoding both audio and video, so we need to check both deps */
744                 if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
745                     @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_PS"])
746                 {
747                     if ([[o_audioCodecs objectAtIndex:[[o_userSelections \
748                         objectForKey:@"trnscdAudioCodec"] intValue]] \
749                         containsObject: @"MUX_PS"])
750                     {
751                         [[o_t5_matrix_encap cellAtRow:0 column:0] setEnabled:YES];
752                         [o_t5_matrix_encap selectCellAtRow:0 column:0];
753                     }
754                 }
755                 if ([[o_videoCodecs objectAtIndex:[[o_userSelections \
756                     objectForKey:@"trnscdVideoCodec"] intValue]] containsObject: @"MUX_TS"])
757                 {
758                     if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
759                         @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_TS"])
760                     {
761                         [[o_t5_matrix_encap cellAtRow:1 column:0] setEnabled:YES];
762                         [o_t5_matrix_encap selectCellAtRow:1 column:0];
763                     }
764                 }
765                 if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
766                     @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_MPEG"])
767                 {
768                     if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
769                         @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_MPEG"])
770                     {
771                         [[o_t5_matrix_encap cellAtRow:2 column:0] setEnabled:YES];
772                         [o_t5_matrix_encap selectCellAtRow:2 column:0];
773                     }
774                 }
775                 if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
776                     @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_OGG"])
777                 {
778                     if ([[o_audioCodecs objectAtIndex:[[o_userSelections \
779                         objectForKey:@"trnscdAudioCodec"] intValue]] containsObject: @"MUX_OGG"])
780                     {
781                         [[o_t5_matrix_encap cellAtRow:3 column:0] setEnabled:YES];
782                         [o_t5_matrix_encap selectCellAtRow:3 column:0];
783                     }
784                 }
785                 if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
786                     @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_RAW"])
787                 {
788                     if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
789                         @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_RAW"])
790                     {
791                         [[o_t5_matrix_encap cellAtRow:4 column:0] setEnabled:YES];
792                         [o_t5_matrix_encap selectCellAtRow:4 column:0];
793                     }
794                 }
795                 if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
796                     @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_ASF"])
797                 {
798                     if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
799                         @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_ASF"])
800                     {
801                         [[o_t5_matrix_encap cellAtRow:5 column:0] setEnabled:YES];
802                         [o_t5_matrix_encap selectCellAtRow:5 column:0];
803                     }
804                 }
805                 if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
806                     @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_AVI"])
807                 {
808                     if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
809                         @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_AVI"])
810                     {
811                         [[o_t5_matrix_encap cellAtRow:6 column:0] setEnabled:YES];
812                         [o_t5_matrix_encap selectCellAtRow:6 column:0];
813                     }
814                 }
815                 if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
816                     @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_MP4"])
817                 {
818                     if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
819                         @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_MP4"])
820                     {
821                         [[o_t5_matrix_encap cellAtRow:7 column:0] setEnabled:YES];
822                         [o_t5_matrix_encap selectCellAtRow:7 column:0];
823                     }
824                 }
825                 if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
826                     @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_MOV"])
827                 {
828                     if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
829                         @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_MOV"])
830                     {
831                         [[o_t5_matrix_encap cellAtRow:8 column:0] setEnabled:YES];
832                         [o_t5_matrix_encap selectCellAtRow:8 column:0];
833                     }
834                 }
835                 if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
836                     @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_WAV"])
837                 {
838                     if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
839                         @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_WAV"])
840                     {
841                         [[o_t5_matrix_encap cellAtRow:9 column:0] setEnabled:YES];
842                         [o_t5_matrix_encap selectCellAtRow:9 column:0];
843                     }
844                 }
845
846             } else {
847
848                 /* we just transcoding the audio */
849
850                 /* select formats supported by the audio codec */
851                 if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
852                     @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_PS"])
853                 {
854                     [[o_t5_matrix_encap cellAtRow:0 column:0] setEnabled:YES];
855                     [o_t5_matrix_encap selectCellAtRow:0 column:0];
856                 }
857                 if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
858                     @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_TS"])
859                 {
860                     [[o_t5_matrix_encap cellAtRow:1 column:0] setEnabled:YES];
861                     [o_t5_matrix_encap selectCellAtRow:1 column:0];
862                 }
863                 if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
864                     @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_MPEG"])
865                 {
866                     [[o_t5_matrix_encap cellAtRow:2 column:0] setEnabled:YES];
867                     [o_t5_matrix_encap selectCellAtRow:2 column:0];
868                 }
869                 if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
870                     @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_OGG"])
871                 {
872                     [[o_t5_matrix_encap cellAtRow:3 column:0] setEnabled:YES];
873                     [o_t5_matrix_encap selectCellAtRow:3 column:0];
874                 }
875                 if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
876                     @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_RAW"])
877                 {
878                     [[o_t5_matrix_encap cellAtRow:4 column:0] setEnabled:YES];
879                     [o_t5_matrix_encap selectCellAtRow:4 column:0];
880                 }
881                 if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
882                     @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_ASF"])
883                 {
884                     [[o_t5_matrix_encap cellAtRow:5 column:0] setEnabled:YES];
885                     [o_t5_matrix_encap selectCellAtRow:5 column:0];
886                 }
887                 if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
888                     @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_AVI"])
889                 {
890                     [[o_t5_matrix_encap cellAtRow:6 column:0] setEnabled:YES];
891                     [o_t5_matrix_encap selectCellAtRow:6 column:0];
892                 }
893                 if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
894                     @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_MP4"])
895                 {
896                     [[o_t5_matrix_encap cellAtRow:7 column:0] setEnabled:YES];
897                     [o_t5_matrix_encap selectCellAtRow:7 column:0];
898                 }
899                 if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
900                     @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_MOV"])
901                 {
902                     [[o_t5_matrix_encap cellAtRow:8 column:0] setEnabled:YES];
903                     [o_t5_matrix_encap selectCellAtRow:8 column:0];
904                 }
905                 if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
906                     @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_WAV"])
907                 {
908                     [[o_t5_matrix_encap cellAtRow:9 column:0] setEnabled:YES];
909                     [o_t5_matrix_encap selectCellAtRow:9 column:0];
910                 }
911             }
912         }
913         else if ([[o_userSelections objectForKey:@"trnscdVideo"] isEqualTo: @"YES"])
914         {
915             /* we are just transcoding the video */
916
917             /* select formats supported by the video-codec */
918
919             if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
920                 @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_PS"])
921             {
922                 [[o_t5_matrix_encap cellAtRow:0 column:0] setEnabled:YES];
923                 [o_t5_matrix_encap selectCellAtRow:0 column:0];
924             }
925             if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
926                 @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_TS"])
927             {
928                 [[o_t5_matrix_encap cellAtRow:1 column:0] setEnabled:YES];
929                 [o_t5_matrix_encap selectCellAtRow:1 column:0];
930             }
931             if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
932                 @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_MPEG"])
933             {
934                 [[o_t5_matrix_encap cellAtRow:2 column:0] setEnabled:YES];
935                 [o_t5_matrix_encap selectCellAtRow:2 column:0];
936             }
937             if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
938                 @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_OGG"])
939             {
940                 [[o_t5_matrix_encap cellAtRow:3 column:0] setEnabled:YES];
941                 [o_t5_matrix_encap selectCellAtRow:3 column:0];
942             }
943             if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
944                 @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_RAW"])
945             {
946                 [[o_t5_matrix_encap cellAtRow:4 column:0] setEnabled:YES];
947                 [o_t5_matrix_encap selectCellAtRow:4 column:0];
948             }
949             if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
950                 @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_ASF"])
951             {
952                 [[o_t5_matrix_encap cellAtRow:5 column:0] setEnabled:YES];
953                 [o_t5_matrix_encap selectCellAtRow:5 column:0];
954             }
955             if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
956                 @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_AVI"])
957             {
958                 [[o_t5_matrix_encap cellAtRow:6 column:0] setEnabled:YES];
959                 [o_t5_matrix_encap selectCellAtRow:6 column:0];
960             }
961             if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
962                 @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_MP4"])
963             {
964                 [[o_t5_matrix_encap cellAtRow:7 column:0] setEnabled:YES];
965                 [o_t5_matrix_encap selectCellAtRow:7 column:0];
966             }
967             if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
968                 @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_MOV"])
969             {
970                 [[o_t5_matrix_encap cellAtRow:8 column:0] setEnabled:YES];
971                 [o_t5_matrix_encap selectCellAtRow:8 column:0];
972             }
973             if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
974                 @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_WAV"])
975             {
976                 [[o_t5_matrix_encap cellAtRow:9 column:0] setEnabled:YES];
977                 [o_t5_matrix_encap selectCellAtRow:9 column:0];
978             }
979         } else {
980             /* we don't do any transcoding
981              * -> enabled the encap-formats allowed when streaming content via
982              * http plus MP4 since this should work fine in most cases */
983
984             /* FIXME: choose a selection of encap-formats based upon the 
985              * actually used codecs */
986
987             /* enable MPEG PS, MPEG TS, MPEG 1, OGG, RAW, ASF, MP4 and MOV
988              * select MPEG PS */
989             [[o_t5_matrix_encap cellAtRow:0 column:0] setEnabled:YES];
990             [[o_t5_matrix_encap cellAtRow:1 column:0] setEnabled:YES];
991             [[o_t5_matrix_encap cellAtRow:2 column:0] setEnabled:YES];
992             [[o_t5_matrix_encap cellAtRow:3 column:0] setEnabled:YES];
993             [[o_t5_matrix_encap cellAtRow:4 column:0] setEnabled:YES];
994             [[o_t5_matrix_encap cellAtRow:5 column:0] setEnabled:YES];
995             [[o_t5_matrix_encap cellAtRow:6 column:0] setEnabled:NO];
996             [[o_t5_matrix_encap cellAtRow:7 column:0] setEnabled:YES];
997             [[o_t5_matrix_encap cellAtRow:8 column:0] setEnabled:YES];
998             [[o_t5_matrix_encap cellAtRow:9 column:0] setEnabled:NO];
999             [[o_t5_matrix_encap cellAtRow:10 column:0] setEnabled:NO];
1000             [o_t5_matrix_encap selectCellAtRow:0 column:0];
1001         }
1002
1003         if ( [o_userSelections objectForKey:@"stmgMhd"] == @"1" )
1004         {
1005             /* if MMS is the streaming protocol, only ASFH is available */
1006             [[o_t5_matrix_encap cellAtRow:0 column:0] setEnabled:NO];
1007             [[o_t5_matrix_encap cellAtRow:1 column:0] setEnabled:NO];
1008             [[o_t5_matrix_encap cellAtRow:2 column:0] setEnabled:NO];
1009             [[o_t5_matrix_encap cellAtRow:3 column:0] setEnabled:NO];
1010             [[o_t5_matrix_encap cellAtRow:4 column:0] setEnabled:NO];
1011             [[o_t5_matrix_encap cellAtRow:5 column:0] setEnabled:NO];
1012             [[o_t5_matrix_encap cellAtRow:6 column:0] setEnabled:NO];
1013             [[o_t5_matrix_encap cellAtRow:7 column:0] setEnabled:NO];
1014             [[o_t5_matrix_encap cellAtRow:8 column:0] setEnabled:NO];
1015             [[o_t5_matrix_encap cellAtRow:9 column:0] setEnabled:NO];
1016             [[o_t5_matrix_encap cellAtRow:10 column:0] setEnabled:YES];
1017             [o_t5_matrix_encap selectCellAtRow:10 column:0];
1018         }
1019         else if ( [o_userSelections objectForKey:@"stmgMhd"] == @"0" )
1020         {
1021             /* if HTTP is the streaming protocol, disable all unsupported
1022              * encap-formats, but don't touch the other ones selected above */
1023             [[o_t5_matrix_encap cellAtRow:6 column:0] setEnabled:NO];
1024             [[o_t5_matrix_encap cellAtRow:7 column:0] setEnabled:NO];
1025             [[o_t5_matrix_encap cellAtRow:8 column:0] setEnabled:NO];
1026             [[o_t5_matrix_encap cellAtRow:9 column:0] setEnabled:NO];
1027             [[o_t5_matrix_encap cellAtRow:10 column:0] setEnabled:NO];
1028         }
1029         else if ( [[o_userSelections objectForKey:@"stmgMhd"] intValue] >= 2 )
1030         {
1031             /* if UDP/RTP is the streaming protocol, only MPEG-TS is available */
1032             [[o_t5_matrix_encap cellAtRow:0 column:0] setEnabled:NO];
1033             [[o_t5_matrix_encap cellAtRow:2 column:0] setEnabled:NO];
1034             [[o_t5_matrix_encap cellAtRow:3 column:0] setEnabled:NO];
1035             [[o_t5_matrix_encap cellAtRow:4 column:0] setEnabled:NO];
1036             [[o_t5_matrix_encap cellAtRow:5 column:0] setEnabled:NO];
1037             [[o_t5_matrix_encap cellAtRow:6 column:0] setEnabled:NO];
1038             [[o_t5_matrix_encap cellAtRow:7 column:0] setEnabled:NO];
1039             [[o_t5_matrix_encap cellAtRow:8 column:0] setEnabled:NO];
1040             [[o_t5_matrix_encap cellAtRow:9 column:0] setEnabled:NO];
1041             [[o_t5_matrix_encap cellAtRow:10 column:0] setEnabled:NO];
1042             [[o_t5_matrix_encap cellAtRow:1 column:0] setEnabled:YES];
1043             [o_t5_matrix_encap selectCellAtRow:1 column:0];
1044         }
1045         int x;
1046         BOOL anythingEnabled;
1047         x = 0;
1048         anythingEnabled = NO;
1049         while (x != [o_t5_matrix_encap numberOfRows])
1050         {
1051             if ([[o_t5_matrix_encap cellAtRow:x column:0] isEnabled])
1052             {
1053                 anythingEnabled = YES;
1054             }
1055             x = (x + 1);
1056         }
1057         if (anythingEnabled == YES)
1058         {
1059             /* go the encap-tab */
1060             [o_tab_pageHolder selectTabViewItemAtIndex:4];
1061         } else {
1062             /* show a sheet that the selected codecs are not compatible */
1063             NSBeginInformationalAlertSheet(_NS("Invalid selection"), _NS("OK"), \
1064                 @"", @"", o_wizard_window, nil, nil, nil, nil, _NS("Your " \
1065                 "chosen codecs are not compatible with each other. For example: " \
1066                 "you cannot mix uncompressed audio with any video codec.\n\n" \
1067                 "Correct your selection and try again."));
1068         }
1069
1070     }
1071     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: @"Encap"])
1072     {
1073         /* get the chosen encap format and store it */
1074         NSNumber * theNum;
1075         theNum = [NSNumber numberWithInt:[[o_t5_matrix_encap selectedCell] tag]];
1076         [o_userSelections setObject:[theNum stringValue] forKey:@"encapFormat"];
1077
1078         /* show either "Streaming 2" or "Transcode 2" to the user */
1079         if ([[o_userSelections objectForKey:@"trnscdOrStrmg"] isEqualToString:@"strmg"])
1080         {
1081             /* we are streaming */
1082             [o_tab_pageHolder selectTabViewItemAtIndex:5];
1083         }else{
1084             /* we are just transcoding */
1085             [o_tab_pageHolder selectTabViewItemAtIndex:6];
1086         }
1087     }
1088     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
1089         @"Streaming 2"])
1090     {
1091         /* store the chosen TTL */
1092         [o_userSelections setObject:[o_t6_fld_ttl stringValue] forKey:@"ttl"];
1093
1094         /* check whether SAP is enabled and store the announce, if needed */
1095         if ([o_t6_ckb_sap state] == NSOnState)
1096         {
1097             [o_userSelections setObject:@"YES" forKey:@"sap"];
1098             [o_userSelections setObject:[o_t6_fld_sap stringValue] forKey:@"sapText"];
1099         } else {
1100             [o_userSelections setObject:@"NO" forKey:@"sap"];
1101         }
1102         
1103         /* local playback? */
1104         if ([o_t6_ckb_local state] == NSOnState)
1105         {
1106             [o_userSelections setObject:@"YES" forKey:@"localPb"];
1107         } else {
1108             [o_userSelections setObject:@"NO" forKey:@"localPb"];
1109         }
1110         
1111         /* go to "Summary" */
1112         [self showSummary];
1113     }
1114     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
1115         @"Transcode 2"])
1116     {
1117         /* local playback? */
1118         if ([o_t7_ckb_local state] == NSOnState)
1119         {
1120             [o_userSelections setObject:@"YES" forKey:@"localPb"];
1121         } else {
1122             [o_userSelections setObject:@"NO" forKey:@"localPb"];
1123         }
1124
1125         /* check whether the path != "" and store it */
1126         if( [[o_t7_fld_filePath stringValue] isEqualToString: @""] )
1127         {
1128             /* complain to the user that "" is no valid path */
1129             NSBeginInformationalAlertSheet(_NS("No file selected"), _NS("OK"), \
1130                 @"", @"", o_wizard_window, nil, nil, nil, nil, _NS("You you " \
1131                 "need to select a file, you want to save to.\n\nEnter either " \
1132                 "a valid path or choose a location through the button's " \
1133                 "dialog-box."));
1134         } else {
1135             [o_userSelections setObject:[o_t7_fld_filePath stringValue] forKey: \
1136                 @"trnscdFilePath"];
1137
1138             /* go to "Summary" */
1139             [self showSummary];
1140         }
1141     }
1142     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
1143         @"Summary"])
1144     {
1145         intf_thread_t * p_intf = VLCIntf;
1146
1147         playlist_t * p_playlist = (playlist_t *)vlc_object_find( p_intf,
1148                             VLC_OBJECT_PLAYLIST, FIND_ANYWHERE);
1149         if( p_playlist )
1150         {
1151             playlist_item_t *p_item = playlist_ItemNew( p_playlist, [[o_userSelections \
1152                 objectForKey:@"pathToStrm"] UTF8String], _("Streaming/Transcoding Wizard") );
1153             playlist_ItemAddOption( p_item, [[o_userSelections objectForKey:@"opts"] UTF8String]);
1154
1155             if(! [[o_userSelections objectForKey:@"partExtractFrom"] isEqualToString:@""] )
1156             {
1157                 playlist_ItemAddOption( p_item, [[@"start-time=" \
1158                     stringByAppendingString: [o_userSelections \
1159                     objectForKey:@"partExtractFrom"]] UTF8String] );
1160             }
1161
1162             if(! [[o_userSelections objectForKey:@"partExtractTo"] isEqualToString:@""] )
1163             {
1164                 playlist_ItemAddOption( p_item, [[@"stop-time=" \
1165                     stringByAppendingString: [o_userSelections objectForKey: \
1166                     @"partExtractTo"]] UTF8String] );
1167             }
1168
1169             playlist_ItemAddOption( p_item, [[@"ttl=" stringByAppendingString: \
1170                 [o_userSelections objectForKey:@"ttl"]] UTF8String] );
1171
1172             playlist_AddItem( p_playlist, p_item, PLAYLIST_GO, PLAYLIST_END );
1173             
1174             playlist_ViewUpdate( p_playlist, VIEW_CATEGORY );
1175
1176             vlc_object_release(p_playlist);
1177         } else {
1178             msg_Err( p_intf, "Uh Oh! Unable to find playlist!" );
1179         }
1180
1181         /* close the window, since we are done */
1182         [o_wizard_window close];
1183     }
1184 }
1185
1186 - (void)rebuildCodecMenus
1187 {
1188     [o_t4_pop_videoCodec removeAllItems];
1189     unsigned int x;
1190     x = 0;
1191     while (x != [o_videoCodecs count])
1192     {
1193         [o_t4_pop_videoCodec addItemWithTitle:[[o_videoCodecs objectAtIndex:x] \
1194             objectAtIndex:0]];
1195         x = (x + 1);
1196     }
1197     [o_t4_pop_audioCodec removeAllItems];
1198     x = 0;
1199     while (x != [o_audioCodecs count])
1200     {
1201         [o_t4_pop_audioCodec addItemWithTitle:[[o_audioCodecs objectAtIndex:x] \
1202             objectAtIndex:0]];
1203         x = (x + 1);
1204     }
1205 }
1206
1207 - (void)showSummary
1208 {
1209     [o_btn_forward setTitle: _NS("Finish")];
1210     [o_t8_fld_inptStream setStringValue:[o_userSelections objectForKey:@"pathToStrm"]];
1211     
1212     if ([[o_userSelections objectForKey:@"localPb"] isEqualToString: @"YES"])
1213     {
1214         [o_t8_fld_local setStringValue: _NS("yes")];
1215     } else {
1216         [o_t8_fld_local setStringValue: _NS("no")];
1217     }
1218
1219     if ([[o_userSelections objectForKey:@"partExtract"] isEqualToString: @"YES"])
1220     {
1221         [o_t8_fld_partExtract setStringValue: [[[[[_NS("yes") \
1222             stringByAppendingString:@" - "] stringByAppendingString: \
1223             _NS("from ")] stringByAppendingString: [o_userSelections \
1224             objectForKey:@"partExtractFrom"]] stringByAppendingString: \
1225             _NS(" to ")] stringByAppendingString: [o_userSelections \
1226             objectForKey:@"partExtractTo"]]];
1227     } else {
1228         [o_t8_fld_partExtract setStringValue: _NS("no")];
1229     }
1230
1231     if ([[o_userSelections objectForKey:@"trnscdVideo"] isEqualToString:@"YES"])
1232     {
1233         [o_t8_fld_trnscdVideo setStringValue: [[[[[_NS("yes") \
1234             stringByAppendingString:@": "] stringByAppendingString: \
1235             [[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey: \
1236             @"trnscdVideoCodec"] intValue]] objectAtIndex:0]] \
1237             stringByAppendingString:@" @ "] stringByAppendingString: \
1238             [o_userSelections objectForKey:@"trnscdVideoBitrate"]] \
1239             stringByAppendingString:@" kb/s"]];
1240     }
1241     else
1242     {
1243         [o_t8_fld_trnscdVideo setStringValue: _NS("no")];
1244     }
1245     if ([[o_userSelections objectForKey:@"trnscdAudio"] isEqualToString:@"YES"])
1246     {
1247         [o_t8_fld_trnscdAudio setStringValue: [[[[[_NS("yes") \
1248         stringByAppendingString:@": "] stringByAppendingString: \
1249         [[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey: \
1250         @"trnscdAudioCodec"] intValue]] objectAtIndex:0]] \
1251         stringByAppendingString:@" @ "] stringByAppendingString: \
1252         [o_userSelections objectForKey:@"trnscdAudioBitrate"]] \
1253         stringByAppendingString:@" kb/s"]];
1254     }
1255     else
1256     {
1257         [o_t8_fld_trnscdAudio setStringValue: _NS("no")];
1258     }
1259
1260
1261     if ([[o_userSelections objectForKey:@"trnscdOrStrmg"] isEqualToString:@"strmg"])
1262     {
1263         /* we are streaming and perhaps also transcoding */
1264         [o_t8_fld_saveFileTo setStringValue: @"-"];
1265         [o_t8_fld_strmgMthd setStringValue: [[o_strmgMthds objectAtIndex: \
1266             [[o_userSelections objectForKey:@"stmgMhd"] intValue]] \
1267             objectAtIndex:1]];
1268         [o_t8_fld_destination setStringValue: [o_userSelections objectForKey: \
1269             @"stmgDest"]];
1270         [o_t8_fld_ttl setStringValue: [o_userSelections objectForKey:@"ttl"]];
1271         if ([[o_userSelections objectForKey:@"sap"] isEqualToString: @"YES"])
1272         {
1273             [o_t8_fld_sap setStringValue: [[_NS("yes") stringByAppendingString:@": "] stringByAppendingString:[o_userSelections objectForKey:@"sapText"]]];
1274         }else{
1275             [o_t8_fld_sap setStringValue: _NS("no")];
1276         }
1277     } else {
1278         /* we are transcoding */
1279         [o_t8_fld_strmgMthd setStringValue: @"-"];
1280         [o_t8_fld_destination setStringValue: @"-"];
1281         [o_t8_fld_ttl setStringValue: @"-"];
1282         [o_t8_fld_sap setStringValue: @"-"];
1283         [o_t8_fld_saveFileTo setStringValue: [o_userSelections objectForKey: \
1284             @"trnscdFilePath"]];
1285     }
1286     [o_t8_fld_encapFormat setStringValue: [[o_encapFormats objectAtIndex: \
1287         [[o_userSelections objectForKey:@"encapFormat"] intValue]] objectAtIndex:1]];
1288
1289     [self createOpts];
1290     [o_t8_fld_mrl setStringValue: [o_userSelections objectForKey:@"opts"]];
1291
1292     [o_tab_pageHolder selectTabViewItemAtIndex:7];
1293 }
1294
1295 - (void) createOpts
1296 {
1297     NSMutableString * o_opts_string = [NSMutableString stringWithString:@""];
1298     NSMutableString *o_trnscdCmd = [NSMutableString stringWithString:@""];
1299     NSMutableString *o_duplicateCmd = [NSMutableString stringWithString:@""];
1300     
1301     /* check whether we transcode the audio and/or the video and compose a
1302      * string reflecting the settings, if needed */
1303     if ([[o_userSelections objectForKey:@"trnscdVideo"] isEqualToString:@"YES"])
1304     {
1305         [o_trnscdCmd appendString: @"transcode{"];
1306         [o_trnscdCmd appendFormat: @"vcodec=%s,vb=%i", [[[o_videoCodecs \
1307             objectAtIndex:[[o_userSelections objectForKey:@"trnscdVideoCodec"] \
1308             intValue]] objectAtIndex:1] UTF8String],  [[o_userSelections \
1309             objectForKey:@"trnscdVideoBitrate"] intValue]];
1310         if ([[o_userSelections objectForKey:@"trnscdAudio"] isEqualToString:@"YES"])
1311         {
1312             [o_trnscdCmd appendString: @","];
1313         } 
1314         else
1315         {
1316             [o_trnscdCmd appendString: @"}:"];
1317         }
1318     }
1319     
1320     /* check whether the user requested local playback. if yes, prepare the
1321      * string, if not, let it empty */
1322     if ([[o_userSelections objectForKey:@"localPb"] isEqualToString:@"YES"])
1323     {
1324         [o_duplicateCmd appendString: @"duplicate{dst=display,dst=\""];
1325     }
1326     
1327     if ([[o_userSelections objectForKey:@"trnscdAudio"] isEqualToString:@"YES"])
1328     {
1329         if ([[o_userSelections objectForKey:@"trnscdVideo"] isEqualToString:@"NO"])
1330         {
1331             /* in case we transcode the audio only, add this */
1332             [o_trnscdCmd appendString: @"transcode{"];
1333         }
1334         [o_trnscdCmd appendFormat: @"acodec=%s,ab=%i}:", [[[o_audioCodecs \
1335             objectAtIndex:[[o_userSelections objectForKey:@"trnscdAudioCodec"] \
1336             intValue]] objectAtIndex:1] UTF8String],  [[o_userSelections \
1337             objectForKey:@"trnscdAudioBitrate"] intValue]];
1338     }
1339     
1340     if ([[o_userSelections objectForKey:@"trnscdOrStrmg"] isEqualToString:@"trnscd"])
1341     {
1342         /* we are just transcoding and dumping the stuff to a file */
1343         [o_opts_string appendFormat: \
1344             @":sout=#%s%sstandard{mux=%s,url=%s,access=file}", [o_duplicateCmd \
1345             UTF8String], [o_trnscdCmd UTF8String], [[[o_encapFormats \
1346             objectAtIndex: [[o_userSelections objectForKey:@"encapFormat"] \
1347             intValue]] objectAtIndex:0] UTF8String], [[o_userSelections \
1348             objectForKey: @"trnscdFilePath"] UTF8String]];
1349
1350     } else {
1351
1352         /* we are streaming */
1353         if ([[o_userSelections objectForKey:@"sap"] isEqualToString:@"YES"])
1354         {
1355             /* SAP-Announcement is requested */
1356             NSMutableString *o_sap_option = [NSMutableString stringWithString:@""];
1357             if([[o_userSelections objectForKey:@"sapText"] isEqualToString:@""])
1358             {
1359                 [o_sap_option appendString: @"sap"];
1360             } else {
1361                 [o_sap_option appendFormat: @"sap,name=\"%s\"",[[o_userSelections \
1362                     objectForKey:@"sapText"] UTF8String]];
1363             }
1364             [o_opts_string appendFormat: \
1365                 @":sout=#%s%sstandard{mux=%s,url=%s,access=%s,%s}", \
1366                 [o_duplicateCmd UTF8String], [o_trnscdCmd UTF8String], \
1367                 [[[o_encapFormats objectAtIndex: [[o_userSelections \
1368                 objectForKey: @"encapFormat"] intValue]] objectAtIndex:0] \
1369                 UTF8String], [[o_userSelections objectForKey: @"stmgDest"] \
1370                 UTF8String], [[[o_strmgMthds objectAtIndex: [[o_userSelections \
1371                 objectForKey: @"stmgMhd"] intValue]] objectAtIndex:0] \
1372                 UTF8String], [o_sap_option UTF8String]];
1373         } else {
1374             /* no SAP, just streaming */
1375             [o_opts_string appendFormat: \
1376                 @":sout=#%s%sstandard{mux=%s,url=%s,access=%s}", \
1377                 [o_duplicateCmd UTF8String], [o_trnscdCmd UTF8String], \
1378                 [[[o_encapFormats objectAtIndex: [[o_userSelections \
1379                 objectForKey: @"encapFormat"] intValue]] objectAtIndex:0] \
1380                 UTF8String], [[o_userSelections objectForKey: \
1381                 @"stmgDest"] UTF8String], [[[o_strmgMthds objectAtIndex: \
1382                 [[o_userSelections objectForKey: @"stmgMhd"] intValue]] \
1383                 objectAtIndex:0] UTF8String]];
1384         }
1385     }
1386
1387     /* check whether the user requested local playback. if yes, close the
1388      * string with an additional bracket */
1389     if ([[o_userSelections objectForKey:@"localPb"] isEqualToString:@"YES"])
1390     {
1391         [o_opts_string appendString: @"\"}"];
1392     }
1393
1394     [o_userSelections setObject:o_opts_string forKey:@"opts"];
1395 }
1396
1397 - (IBAction)prevTab:(id)sender
1398 {
1399     if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: @"Summary"])
1400     {
1401         /* check whether we are streaming or transcoding and go back */
1402         if ([[o_userSelections objectForKey:@"trnscdOrStrmg"] isEqualToString:@"strmg"])
1403         {
1404             /* show "Streaming 2" */
1405             [o_tab_pageHolder selectTabViewItemAtIndex:5];
1406         }else{
1407             /* show "Transcode 2" */
1408             [o_tab_pageHolder selectTabViewItemAtIndex:6];
1409         }
1410         /* rename the forward-button */
1411         [o_btn_forward setTitle: _NS("Next")];
1412     }
1413     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
1414         @"Transcode 2"])
1415     {
1416         /* show "Encap" */
1417         [o_tab_pageHolder selectTabViewItemAtIndex:4];
1418     }
1419     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
1420         @"Streaming 2"])
1421     {
1422         /* show "Encap" */
1423         [o_tab_pageHolder selectTabViewItemAtIndex:4];
1424     }
1425     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
1426         @"Encap"])
1427     {
1428         /* show "Transcode 1" */
1429         [o_tab_pageHolder selectTabViewItemAtIndex:3];
1430     }
1431     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
1432         @"Streaming 1"])
1433     {
1434         /* show "Input" */
1435         [o_tab_pageHolder selectTabViewItemAtIndex:1];
1436     }
1437     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
1438         @"Transcode 1"])
1439     {
1440         if ([[o_userSelections objectForKey:@"trnscdOrStrmg"] isEqualToString:@"strmg"])
1441         {
1442             /* show "Streaming 1" */
1443             [o_tab_pageHolder selectTabViewItemAtIndex:2];
1444         }else{
1445             /* show "Input" */
1446             [o_tab_pageHolder selectTabViewItemAtIndex:1];
1447         }
1448     }
1449     else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: \
1450         @"Input"])
1451     {
1452         /* reset the wizard before going backwards. Otherwise, we might get
1453          * unwanted behaviours in the Encap-Selection */
1454         [self resetWizard];
1455         /* show "Hello" */
1456         [o_tab_pageHolder selectTabViewItemAtIndex:0];
1457         /* disable backwards-btn */
1458         [o_btn_backward setEnabled:NO];
1459     }
1460 }
1461
1462 - (IBAction)t1_mrInfo_streaming:(id)sender
1463 {
1464     /* show a sheet for the help */
1465     /* since NSAlert does not exist on OSX < 10.3, we use our own implementation */
1466     [o_wh_txt_title setStringValue: _NS("Stream to network")];
1467     [o_wh_txt_text setStringValue: _NS("Use this to stream on a network.")];
1468     [NSApp beginSheet: o_wizardhelp_window
1469             modalForWindow: o_wizard_window
1470             modalDelegate: o_wizardhelp_window
1471             didEndSelector: nil
1472             contextInfo: nil];
1473 }
1474
1475 - (IBAction)t1_mrInfo_transcode:(id)sender
1476 {
1477     /* show a sheet for the help */
1478     [o_wh_txt_title setStringValue: _NS("Transcode/Save to file")];
1479     [o_wh_txt_text setStringValue: _NS("Use this to save a stream to a file. You "\
1480         "have the possibility to reencode the stream. You can save whatever "\
1481         "VLC can read.\nPlease notice that VLC is not very suited " \
1482         "for file to file transcoding. You should use its transcoding " \
1483         "features to save network streams, for example.")];
1484     [NSApp beginSheet: o_wizardhelp_window
1485             modalForWindow: o_wizard_window
1486             modalDelegate: o_wizardhelp_window
1487             didEndSelector: nil
1488             contextInfo: nil];
1489 }
1490
1491 - (IBAction)t2_addNewStream:(id)sender
1492 {
1493     NSOpenPanel * openPanel = [NSOpenPanel openPanel];
1494     SEL sel = @selector(t2_getNewStreamFromDialog:returnCode:contextInfo:);
1495     [openPanel beginSheetForDirectory:nil file:nil types:nil modalForWindow: \
1496         o_wizard_window modalDelegate:self didEndSelector:sel contextInfo:nil];
1497 }
1498
1499 - (void)t2_getNewStreamFromDialog: (NSOpenPanel *)sheet returnCode: \
1500     (int)returnCode contextInfo: (void *)contextInfo
1501 {
1502     if (returnCode == NSOKButton)
1503     {
1504         [o_t2_fld_pathToNewStrm setStringValue: [@"file://" \
1505             stringByAppendingString: [sheet filename]]];
1506     }
1507 }
1508
1509 - (IBAction)t2_chooseStreamOrPlst:(id)sender
1510 {
1511     /* enable and disable the respective items depending on user's choice */
1512     NSString *o_mode;
1513     o_mode = [[o_t2_matrix_inputSourceType selectedCell] title];
1514
1515     if( [o_mode isEqualToString: _NS("Select a stream")] )
1516     {
1517         [o_t2_btn_chooseFile setEnabled:YES];
1518         [o_t2_fld_pathToNewStrm setEnabled:YES];
1519         [o_t2_tbl_plst setEnabled:NO];
1520     } else {
1521         [o_t2_btn_chooseFile setEnabled:NO];
1522         [o_t2_fld_pathToNewStrm setEnabled:NO];
1523         [o_t2_tbl_plst setEnabled:YES];
1524     }
1525 }
1526
1527 - (IBAction)t2_enableExtract:(id)sender
1528 {
1529     /* enable/disable the respective items */
1530     if([o_t2_ckb_enblPartExtrct state] == NSOnState)
1531     {
1532         [o_t2_fld_prtExtrctFrom setEnabled:YES];
1533         [o_t2_fld_prtExtrctTo setEnabled:YES];
1534     } else {
1535         [o_t2_fld_prtExtrctFrom setEnabled:NO];
1536         [o_t2_fld_prtExtrctTo setEnabled:NO];
1537         [o_t2_fld_prtExtrctFrom setStringValue:@""];
1538         [o_t2_fld_prtExtrctTo setStringValue:@""];
1539     }
1540 }
1541
1542 - (IBAction)t3_strmMthdChanged:(id)sender
1543 {
1544     /* change the captions of o_t3_txt_destInfo according to the chosen
1545      * streaming method */
1546     int mode;
1547     mode = [[o_t3_matrix_stmgMhd selectedCell] tag];
1548     if( mode == 0 )
1549     {
1550         /* HTTP */
1551         [o_t3_txt_destInfo setStringValue: [[o_strmgMthds objectAtIndex:0] \
1552             objectAtIndex:2]];
1553         [o_t3_txt_strgMthdInfo setStringValue: [[o_strmgMthds objectAtIndex:0] \
1554             objectAtIndex:3]];
1555     }
1556     else if( mode == 1 )
1557     {
1558         /* MMS */
1559         [o_t3_txt_destInfo setStringValue: [[o_strmgMthds objectAtIndex:1] \
1560             objectAtIndex:2]];
1561         [o_t3_txt_strgMthdInfo setStringValue: [[o_strmgMthds objectAtIndex:1] \
1562             objectAtIndex:3]];
1563     }
1564     else if( mode == 2 )
1565     {
1566         /* UDP-Unicast */
1567         [o_t3_txt_destInfo setStringValue: [[o_strmgMthds objectAtIndex:2] \
1568             objectAtIndex:2]];
1569         [o_t3_txt_strgMthdInfo setStringValue: [[o_strmgMthds objectAtIndex:2] \
1570         objectAtIndex:3]];
1571     }
1572     else if( mode == 3 )
1573     {
1574         /* UDP-Multicast */
1575         [o_t3_txt_destInfo setStringValue: [[o_strmgMthds objectAtIndex:3] \
1576             objectAtIndex:2]];
1577         [o_t3_txt_strgMthdInfo setStringValue: [[o_strmgMthds objectAtIndex:3] \
1578         objectAtIndex:3]];
1579     }
1580     else if( mode == 4 )
1581     {
1582         /* RTP-Unicast */
1583         [o_t3_txt_destInfo setStringValue: [[o_strmgMthds objectAtIndex:4] \
1584             objectAtIndex:2]];
1585         [o_t3_txt_strgMthdInfo setStringValue: [[o_strmgMthds objectAtIndex:4] \
1586             objectAtIndex:3]];
1587     }
1588     else if( mode == 5 )
1589     {
1590         /* RTP-Multicast */
1591         [o_t3_txt_destInfo setStringValue: [[o_strmgMthds objectAtIndex:5] \
1592             objectAtIndex:2]];
1593         [o_t3_txt_strgMthdInfo setStringValue: [[o_strmgMthds objectAtIndex:5] \
1594         objectAtIndex:3]];
1595     }
1596 }
1597
1598 - (IBAction)t4_AudCdcChanged:(id)sender
1599 {
1600     /* update codec info */
1601     [o_t4_txt_hintAudio setStringValue:[[o_audioCodecs objectAtIndex: \
1602         [o_t4_pop_audioCodec indexOfSelectedItem]] objectAtIndex:2]];
1603 }
1604
1605 - (IBAction)t4_enblAudTrnscd:(id)sender
1606 {
1607     /* enable/disable the respective items */
1608     if([o_t4_ckb_audio state] == NSOnState)
1609     {
1610         [o_t4_pop_audioCodec setEnabled:YES];
1611         [o_t4_pop_audioBitrate setEnabled:YES];
1612         [o_t4_txt_hintAudio setStringValue: _NS("Select your audio codec. "\
1613         "Click one to get more information.")];
1614     } else {
1615         [o_t4_pop_audioCodec setEnabled:NO];
1616         [o_t4_pop_audioBitrate setEnabled:NO];
1617         [o_t4_txt_hintAudio setStringValue: _NS("If your stream has audio " \
1618         "and you want to transcode it, enable this.")];
1619     }
1620 }
1621
1622 - (IBAction)t4_enblVidTrnscd:(id)sender
1623 {
1624     /* enable/disable the respective items */
1625     if([o_t4_ckb_video state] == NSOnState)
1626     {
1627         [o_t4_pop_videoCodec setEnabled:YES];
1628         [o_t4_pop_videoBitrate setEnabled:YES];
1629         [o_t4_txt_hintVideo setStringValue: _NS("Select your video codec. "\
1630         "Click one to get more information.")];
1631     } else {
1632         [o_t4_pop_videoCodec setEnabled:NO];
1633         [o_t4_pop_videoBitrate setEnabled:NO];
1634         [o_t4_txt_hintVideo setStringValue: _NS("If your stream has video " \
1635         "and you want to transcode it, enable this.")];
1636     }
1637 }
1638
1639 - (IBAction)t4_VidCdcChanged:(id)sender
1640 {
1641     /* update codec info */
1642     [o_t4_txt_hintVideo setStringValue:[[o_videoCodecs objectAtIndex: \
1643         [o_t4_pop_videoCodec indexOfSelectedItem]] objectAtIndex:2]];
1644 }
1645
1646 - (IBAction)t6_enblSapAnnce:(id)sender
1647 {
1648     /* enable/disable input fld */
1649     if([o_t6_ckb_sap state] == NSOnState)
1650     {
1651         [o_t6_fld_sap setEnabled:YES];
1652     } else {
1653         [o_t6_fld_sap setEnabled:NO];
1654         [o_t6_fld_sap setStringValue:@""];
1655     }
1656 }
1657
1658 - (IBAction)t6_mrInfo_ttl:(id)sender
1659 {
1660     /* show a sheet for the help */
1661     [o_wh_txt_title setStringValue: _NS("Time-To-Live (TTL)")];
1662     [o_wh_txt_text setStringValue: _NS("Define the TTL (Time-To-Live) of the stream. "\
1663             "This parameter is the maximum number of routers your stream can go " \
1664             "through. If you don't know what it means, or if you want to stream on " \
1665             "your local network only, leave this setting to 1.")];
1666     [NSApp beginSheet: o_wizardhelp_window
1667             modalForWindow: o_wizard_window
1668             modalDelegate: o_wizardhelp_window
1669             didEndSelector: nil
1670             contextInfo: nil];
1671 }
1672
1673 - (IBAction)t6_mrInfo_sap:(id)sender
1674 {
1675     /* show a sheet for the help */
1676     [o_wh_txt_title setStringValue: _NS("SAP Announce")];
1677     [o_wh_txt_text setStringValue: _NS("When streaming using UDP, you can " \
1678         "announce your streams using the SAP/SDP announcing protocol. This " \
1679         "way, the clients won't have to type in the multicast address, it " \
1680         "will appear in their playlist if they enable the SAP extra interface.\n" \
1681         "If you want to give a name to your stream, enter it here, " \
1682         "else, a default name will be used.")];
1683     [NSApp beginSheet: o_wizardhelp_window
1684             modalForWindow: o_wizard_window
1685             modalDelegate: o_wizardhelp_window
1686             didEndSelector: nil
1687             contextInfo: nil];
1688 }
1689
1690 - (IBAction)t67_mrInfo_local:(id)sender
1691 {
1692     /* show a sheet for the help */
1693     NSBeginInformationalAlertSheet(_NS("Local playback"), \
1694             _NS("OK"), @"", @"", o_wizard_window, nil, nil, nil, nil, \
1695             _NS("When this option is enabled, the stream will be both played " \
1696             "and transcoded/streamed.\n\nNote that this requires much more " \
1697             "CPU power than simple transcoding or streaming."));
1698 }
1699
1700 - (IBAction)t7_selectTrnscdDestFile:(id)sender
1701 {
1702     /* provide a save-to-dialogue, so the user can choose a location for his/her new file */
1703     NSSavePanel * savePanel = [NSSavePanel savePanel];
1704     SEL sel = @selector(t7_getTrnscdDestFile:returnCode:contextInfo:);
1705     NSString * theEncapFormat = [[o_encapFormats objectAtIndex: \
1706         [[o_userSelections objectForKey:@"encapFormat"] intValue]] \
1707         objectAtIndex:0];
1708     
1709     /* don't use ".ps" as suffix, since the OSX Finder confuses our creations 
1710      * with PostScript-files and wants to open them with Preview.app */
1711     if (theEncapFormat != @"ps")
1712     {
1713         [savePanel setRequiredFileType: theEncapFormat];
1714     } else {
1715         [savePanel setRequiredFileType: @"mpg"];
1716     }
1717     
1718     [savePanel setCanSelectHiddenExtension:YES];
1719     [savePanel beginSheetForDirectory:nil file:nil modalForWindow: \
1720         o_wizard_window modalDelegate:self didEndSelector:sel contextInfo:nil];
1721 }
1722
1723 - (void)t7_getTrnscdDestFile: (NSSavePanel *)sheet returnCode: \
1724     (int)returnCode contextInfo: (void *)contextInfo
1725 {
1726     if (returnCode == NSOKButton)
1727     {
1728         /* output returned path to text-field */
1729         [o_t7_fld_filePath setStringValue:[sheet filename]];
1730     }
1731 }
1732
1733 - (IBAction)wh_closeSheet:(id)sender
1734 {
1735     /* close the help sheet */
1736     [NSApp endSheet:o_wizardhelp_window];
1737     [o_wizardhelp_window close];
1738 }
1739
1740 @end