]> git.sesse.net Git - vlc/blob - modules/gui/macosx/prefs_widgets.m
Merge branch 'master' into lpcm_encoder
[vlc] / modules / gui / macosx / prefs_widgets.m
1 /*****************************************************************************
2  * prefs_widgets.m: Preferences controls
3  *****************************************************************************
4  * Copyright (C) 2002-2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Derk-Jan Hartman <hartman at videolan.org>
8  *          Jérôme Decoodt <djc at videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>                                      /* malloc(), free() */
29 #include <string.h>
30
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34
35 #include <vlc_common.h>
36 #include <vlc_keys.h>
37
38 #include "intf.h"
39 #include "prefs_widgets.h"
40
41 #define PREFS_WRAP 300
42 #define OFFSET_RIGHT 20
43 #define OFFSET_BETWEEN 2
44
45 #define UPWARDS_WHITE_ARROW                 "\xE2\x87\xA7"
46 #define OPTION_KEY                          "\xE2\x8C\xA5"
47 #define UP_ARROWHEAD                        "\xE2\x8C\x83"
48 #define PLACE_OF_INTEREST_SIGN              "\xE2\x8C\x98"
49
50 #define POPULATE_A_KEY( o_menu, string, value )                             \
51 {                                                                           \
52     NSMenuItem *o_mi;                                                       \
53 /*  Normal */                                                               \
54     o_mi = [[NSMenuItem alloc] initWithTitle:string                         \
55         action:nil keyEquivalent:@""];                                      \
56     [o_mi setKeyEquivalentModifierMask:                                     \
57         0];                                                                 \
58     [o_mi setAlternate: NO];                                                \
59     [o_mi setTag:                                                           \
60         ( value )];                                                         \
61     [o_menu addItem: o_mi];                                                 \
62 /*  Ctrl */                                                                 \
63     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
64         [[NSString stringWithUTF8String:                                    \
65             UP_ARROWHEAD                                                    \
66         ] stringByAppendingString: string]                                  \
67         action:nil keyEquivalent:@""];                                      \
68     [o_mi setKeyEquivalentModifierMask:                                     \
69         NSControlKeyMask];                                                  \
70     [o_mi setAlternate: YES];                                               \
71     [o_mi setTag:                                                           \
72         KEY_MODIFIER_CTRL | ( value )];                                     \
73     [o_menu addItem: o_mi];                                                 \
74 /* Ctrl+Alt */                                                              \
75     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
76         [[NSString stringWithUTF8String:                                    \
77             UP_ARROWHEAD OPTION_KEY                                         \
78         ] stringByAppendingString: string]                                  \
79         action:nil keyEquivalent:@""];                                      \
80     [o_mi setKeyEquivalentModifierMask:                                     \
81         NSControlKeyMask | NSAlternateKeyMask];                             \
82     [o_mi setAlternate: YES];                                               \
83     [o_mi setTag:                                                           \
84         (KEY_MODIFIER_CTRL | KEY_MODIFIER_ALT) | ( value )];                \
85     [o_menu addItem: o_mi];                                                 \
86 /* Ctrl+Shift */                                                            \
87     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
88         [[NSString stringWithUTF8String:                                    \
89             UP_ARROWHEAD UPWARDS_WHITE_ARROW                                \
90         ] stringByAppendingString: string]                                  \
91         action:nil keyEquivalent:@""];                                      \
92     [o_mi setKeyEquivalentModifierMask:                                     \
93        NSControlKeyMask | NSShiftKeyMask];                                  \
94     [o_mi setAlternate: YES];                                               \
95     [o_mi setTag:                                                           \
96         (KEY_MODIFIER_CTRL | KEY_MODIFIER_SHIFT) | ( value )];              \
97     [o_menu addItem: o_mi];                                                 \
98 /* Ctrl+Apple */                                                            \
99     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
100         [[NSString stringWithUTF8String:                                    \
101             UP_ARROWHEAD PLACE_OF_INTEREST_SIGN                             \
102         ] stringByAppendingString: string]                                  \
103         action:nil keyEquivalent:@""];                                      \
104     [o_mi setKeyEquivalentModifierMask:                                     \
105         NSControlKeyMask | NSCommandKeyMask];                               \
106     [o_mi setAlternate: YES];                                               \
107     [o_mi setTag:                                                           \
108         (KEY_MODIFIER_CTRL | KEY_MODIFIER_COMMAND) | ( value )];            \
109     [o_menu addItem: o_mi];                                                 \
110 /* Ctrl+Alt+Shift */                                                        \
111     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
112         [[NSString stringWithUTF8String:                                    \
113             UP_ARROWHEAD OPTION_KEY UPWARDS_WHITE_ARROW                     \
114         ] stringByAppendingString: string]                                  \
115         action:nil keyEquivalent:@""];                                      \
116     [o_mi setKeyEquivalentModifierMask:                                     \
117         NSControlKeyMask | NSAlternateKeyMask | NSShiftKeyMask];            \
118     [o_mi setAlternate: YES];                                               \
119     [o_mi setTag:                                                           \
120         (KEY_MODIFIER_CTRL | KEY_MODIFIER_ALT | KEY_MODIFIER_SHIFT) |       \
121              ( value )];                                                    \
122     [o_menu addItem: o_mi];                                                 \
123 /* Ctrl+Alt+Apple */                                                        \
124     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
125         [[NSString stringWithUTF8String:                                    \
126             UP_ARROWHEAD OPTION_KEY PLACE_OF_INTEREST_SIGN                  \
127         ] stringByAppendingString: string]                                  \
128         action:nil keyEquivalent:@""];                                      \
129     [o_mi setKeyEquivalentModifierMask:                                     \
130         NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask];          \
131     [o_mi setAlternate: YES];                                               \
132     [o_mi setTag:                                                           \
133         (KEY_MODIFIER_CTRL | KEY_MODIFIER_ALT | KEY_MODIFIER_COMMAND) |     \
134             ( value )];                                                     \
135     [o_menu addItem: o_mi];                                                 \
136 /* Ctrl+Shift+Apple */                                                      \
137     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
138         [[NSString stringWithUTF8String:                                    \
139             UP_ARROWHEAD UPWARDS_WHITE_ARROW PLACE_OF_INTEREST_SIGN         \
140         ] stringByAppendingString: string]                                  \
141         action:nil keyEquivalent:@""];                                      \
142     [o_mi setKeyEquivalentModifierMask:                                     \
143         NSControlKeyMask | NSShiftKeyMask | NSCommandKeyMask];              \
144     [o_mi setAlternate: YES];                                               \
145     [o_mi setTag:                                                           \
146         (KEY_MODIFIER_CTRL | KEY_MODIFIER_SHIFT | KEY_MODIFIER_COMMAND) |   \
147             ( value )];                                                     \
148     [o_menu addItem: o_mi];                                                 \
149 /* Ctrl+Alt+Shift+Apple */                                                  \
150     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
151         [[NSString stringWithUTF8String:                                    \
152             UP_ARROWHEAD OPTION_KEY UPWARDS_WHITE_ARROW                     \
153                 PLACE_OF_INTEREST_SIGN                                      \
154         ] stringByAppendingString: string]                                  \
155         action:nil keyEquivalent:@""];                                      \
156     [o_mi setKeyEquivalentModifierMask:                                     \
157         NSControlKeyMask | NSAlternateKeyMask | NSShiftKeyMask |            \
158             NSCommandKeyMask];                                              \
159     [o_mi setAlternate: YES];                                               \
160     [o_mi setTag:                                                           \
161         (KEY_MODIFIER_CTRL | KEY_MODIFIER_ALT | KEY_MODIFIER_SHIFT |        \
162             KEY_MODIFIER_COMMAND) | ( value )];                             \
163     [o_menu addItem: o_mi];                                                 \
164 /* Alt */                                                                   \
165     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
166         [[NSString stringWithUTF8String:                                    \
167             OPTION_KEY                                                      \
168         ] stringByAppendingString: string]                                  \
169         action:nil keyEquivalent:@""];                                      \
170     [o_mi setKeyEquivalentModifierMask:                                     \
171         NSAlternateKeyMask];                                                \
172     [o_mi setAlternate: YES];                                               \
173     [o_mi setTag:                                                           \
174         KEY_MODIFIER_ALT | ( value )];                                      \
175     [o_menu addItem: o_mi];                                                 \
176 /* Alt+Shift */                                                             \
177     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
178         [[NSString stringWithUTF8String:                                    \
179             OPTION_KEY UPWARDS_WHITE_ARROW                                  \
180         ] stringByAppendingString: string]                                  \
181         action:nil keyEquivalent:@""];                                      \
182     [o_mi setKeyEquivalentModifierMask:                                     \
183         NSAlternateKeyMask | NSShiftKeyMask];                               \
184     [o_mi setAlternate: YES];                                               \
185     [o_mi setTag:                                                           \
186         (KEY_MODIFIER_ALT | KEY_MODIFIER_SHIFT) | ( value )];               \
187     [o_menu addItem: o_mi];                                                 \
188 /* Alt+Apple */                                                             \
189     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
190         [[NSString stringWithUTF8String:                                    \
191             OPTION_KEY PLACE_OF_INTEREST_SIGN                               \
192         ] stringByAppendingString: string]                                  \
193         action:nil keyEquivalent:@""];                                      \
194     [o_mi setKeyEquivalentModifierMask:                                     \
195         NSAlternateKeyMask | NSCommandKeyMask];                             \
196     [o_mi setAlternate: YES];                                               \
197     [o_mi setTag:                                                           \
198         (KEY_MODIFIER_ALT | KEY_MODIFIER_COMMAND) | ( value )];             \
199     [o_menu addItem: o_mi];                                                 \
200 /* Alt+Shift+Apple */                                                       \
201     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
202         [[NSString stringWithUTF8String:                                    \
203             OPTION_KEY UPWARDS_WHITE_ARROW PLACE_OF_INTEREST_SIGN           \
204         ] stringByAppendingString: string]                                  \
205         action:nil keyEquivalent:@""];                                      \
206     [o_mi setKeyEquivalentModifierMask:                                     \
207         NSAlternateKeyMask | NSShiftKeyMask | NSCommandKeyMask];            \
208     [o_mi setAlternate: YES];                                               \
209     [o_mi setTag:                                                           \
210         (KEY_MODIFIER_ALT | KEY_MODIFIER_SHIFT | KEY_MODIFIER_COMMAND) |    \
211             ( value )];                                                     \
212     [o_menu addItem: o_mi];                                                 \
213 /* Shift */                                                                 \
214     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
215         [[NSString stringWithUTF8String:                                    \
216             UPWARDS_WHITE_ARROW                                             \
217         ] stringByAppendingString: string]                                  \
218         action:nil keyEquivalent:@""];                                      \
219     [o_mi setKeyEquivalentModifierMask:                                     \
220         NSShiftKeyMask];                                                    \
221     [o_mi setAlternate: YES];                                               \
222     [o_mi setTag:                                                           \
223         KEY_MODIFIER_SHIFT | ( value )];                                    \
224     [o_menu addItem: o_mi];                                                 \
225 /* Shift+Apple */                                                           \
226     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
227         [[NSString stringWithUTF8String:                                    \
228             UPWARDS_WHITE_ARROW PLACE_OF_INTEREST_SIGN                      \
229         ] stringByAppendingString: string]                                  \
230         action:nil keyEquivalent:@""];                                      \
231     [o_mi setKeyEquivalentModifierMask:                                     \
232         NSShiftKeyMask | NSCommandKeyMask];                                 \
233     [o_mi setAlternate: YES];                                               \
234     [o_mi setTag:                                                           \
235         (KEY_MODIFIER_SHIFT | KEY_MODIFIER_COMMAND) | ( value )];           \
236     [o_menu addItem: o_mi];                                                 \
237 /* Apple */                                                                 \
238     o_mi = [[NSMenuItem alloc] initWithTitle:                               \
239         [[NSString stringWithUTF8String:                                    \
240         PLACE_OF_INTEREST_SIGN                                              \
241         ] stringByAppendingString: string]                                  \
242         action:nil keyEquivalent:@""];                                      \
243     [o_mi setKeyEquivalentModifierMask:                                     \
244         NSCommandKeyMask];                                                  \
245     [o_mi setAlternate: YES];                                               \
246     [o_mi setTag:                                                           \
247         KEY_MODIFIER_COMMAND | ( value )];                                  \
248     [o_menu addItem: o_mi];                                                 \
249 }
250
251 #define ADD_LABEL( o_label, superFrame, x_offset, my_y_offset, label,       \
252     tooltip )                                                               \
253 {                                                                           \
254     NSRect s_rc = superFrame;                                               \
255     s_rc.size.height = 17;                                                  \
256     s_rc.origin.x = x_offset - 3;                                           \
257     s_rc.origin.y = superFrame.size.height - 17 + my_y_offset;              \
258     o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];           \
259     [o_label setDrawsBackground: NO];                                       \
260     [o_label setBordered: NO];                                              \
261     [o_label setEditable: NO];                                              \
262     [o_label setSelectable: NO];                                            \
263     [o_label setStringValue: label];                                        \
264     [o_label setToolTip: tooltip];                                          \
265     [o_label setFont:[NSFont systemFontOfSize:0]];                          \
266     [o_label sizeToFit];                                                    \
267 }
268
269 #define ADD_TEXTFIELD( o_textfield, superFrame, x_offset, my_y_offset,      \
270     my_width, tooltip, init_value )                                         \
271 {                                                                           \
272     NSRect s_rc = superFrame;                                               \
273     s_rc.origin.x = x_offset;                                               \
274     s_rc.origin.y = my_y_offset;                                            \
275     s_rc.size.height = 22;                                                  \
276     s_rc.size.width = my_width;                                             \
277     o_textfield = [[[NSTextField alloc] initWithFrame: s_rc] retain];       \
278     [o_textfield setFont:[NSFont systemFontOfSize:0]];                      \
279     [o_textfield setToolTip: tooltip];                                      \
280     [o_textfield setStringValue: init_value];                               \
281 }
282
283 #define ADD_SECURETEXTFIELD( o_textfield, superFrame, x_offset, my_y_offset,      \
284 my_width, tooltip, init_value )                                         \
285 {                                                                           \
286 NSRect s_rc = superFrame;                                               \
287 s_rc.origin.x = x_offset;                                               \
288 s_rc.origin.y = my_y_offset;                                            \
289 s_rc.size.height = 22;                                                  \
290 s_rc.size.width = my_width;                                             \
291 o_textfield = [[[NSSecureTextField alloc] initWithFrame: s_rc] retain];       \
292 [o_textfield setFont:[NSFont systemFontOfSize:0]];                      \
293 [o_textfield setToolTip: tooltip];                                      \
294 [o_textfield setStringValue: init_value];                               \
295 }
296
297 #define ADD_COMBO( o_combo, superFrame, x_offset, my_y_offset, x2_offset,   \
298     tooltip )                                                               \
299 {                                                                           \
300     NSRect s_rc = superFrame;                                               \
301     s_rc.origin.x = x_offset + 2;                                           \
302     s_rc.origin.y = my_y_offset;                                            \
303     s_rc.size.height = 26;                                                  \
304     s_rc.size.width = superFrame.size.width + 2 - s_rc.origin.x -           \
305         (x2_offset);                                                        \
306     o_combo = [[[NSComboBox alloc] initWithFrame: s_rc] retain];            \
307     [o_combo setFont:[NSFont systemFontOfSize:0]];                          \
308     [o_combo setToolTip: tooltip];                                          \
309     [o_combo setUsesDataSource:TRUE];                                       \
310     [o_combo setDataSource:self];                                           \
311     [o_combo setNumberOfVisibleItems:10];                                   \
312     [o_combo setCompletes:YES];                                             \
313 }
314
315 #define ADD_RIGHT_BUTTON( o_button, superFrame, x_offset, my_y_offset,      \
316     tooltip, title )                                                        \
317 {                                                                           \
318     NSRect s_rc = superFrame;                                               \
319     o_button = [[[NSButton alloc] initWithFrame: s_rc] retain];             \
320     [o_button setButtonType: NSMomentaryPushInButton];                      \
321     [o_button setBezelStyle: NSRoundedBezelStyle];                          \
322     [o_button setTitle: title];                                             \
323     [o_button setFont:[NSFont systemFontOfSize:0]];                         \
324     [o_button sizeToFit];                                                   \
325     s_rc = [o_button frame];                                                \
326     s_rc.origin.x = superFrame.size.width - [o_button frame].size.width - 6;\
327     s_rc.origin.y = my_y_offset - 6;                                        \
328     s_rc.size.width += 12;                                                  \
329     [o_button setFrame: s_rc];                                              \
330     [o_button setToolTip: tooltip];                                         \
331     [o_button setTarget: self];                                             \
332     [o_button setAction: @selector(openFileDialog:)];                       \
333 }
334
335 #define ADD_POPUP( o_popup, superFrame, x_offset, my_y_offset, x2_offset,   \
336     tooltip )                                                               \
337 {                                                                           \
338     NSRect s_rc = superFrame;                                               \
339     s_rc.origin.x = x_offset - 1;                                           \
340     s_rc.origin.y = my_y_offset;                                            \
341     s_rc.size.height = 26;                                                  \
342     s_rc.size.width = superFrame.size.width + 2 - s_rc.origin.x -           \
343         (x2_offset);                                                        \
344     o_popup = [[[NSPopUpButton alloc] initWithFrame: s_rc] retain];         \
345     [o_popup setFont:[NSFont systemFontOfSize:0]];                          \
346     [o_popup setToolTip: tooltip];                                          \
347 }
348
349 #define ADD_STEPPER( o_stepper, superFrame, x_offset, my_y_offset, tooltip, \
350     lower, higher )                                                         \
351 {                                                                           \
352     NSRect s_rc = superFrame;                                               \
353     s_rc.origin.x = x_offset;                                               \
354     s_rc.origin.y = my_y_offset;                                            \
355     s_rc.size.height = 23;                                                  \
356     s_rc.size.width = 23;                                                   \
357     o_stepper = [[[NSStepper alloc] initWithFrame: s_rc] retain];           \
358     [o_stepper setFont:[NSFont systemFontOfSize:0]];                        \
359     [o_stepper setToolTip: tooltip];                                        \
360     [o_stepper setMaxValue: higher];                                        \
361     [o_stepper setMinValue: lower];                                         \
362     [o_stepper setTarget: self];                                            \
363     [o_stepper setAction: @selector(stepperChanged:)];                      \
364     [o_stepper sendActionOn:NSLeftMouseUpMask | NSLeftMouseDownMask |       \
365         NSLeftMouseDraggedMask];                                            \
366 }
367
368 #define ADD_SLIDER( o_slider, superFrame, x_offset, my_y_offset, my_width,  \
369     tooltip, lower, higher )                                                \
370 {                                                                           \
371     NSRect s_rc = superFrame;                                               \
372     s_rc.origin.x = x_offset;                                               \
373     s_rc.origin.y = my_y_offset;                                            \
374     s_rc.size.height = 21;                                                  \
375     s_rc.size.width = my_width;                                             \
376     o_slider = [[[NSSlider alloc] initWithFrame: s_rc] retain];             \
377     [o_slider setFont:[NSFont systemFontOfSize:0]];                         \
378     [o_slider setToolTip: tooltip];                                         \
379     [o_slider setMaxValue: higher];                                         \
380     [o_slider setMinValue: lower];                                          \
381 }
382
383 #define ADD_CHECKBOX( o_checkbox, superFrame, x_offset, my_y_offset, label, \
384     tooltip, init_value, position )                                         \
385 {                                                                           \
386     NSRect s_rc = superFrame;                                               \
387     s_rc.size.height = 18;                                                  \
388     s_rc.origin.x = x_offset - 2;                                           \
389     s_rc.origin.y = superFrame.size.height - 18 + my_y_offset;              \
390     o_checkbox = [[[NSButton alloc] initWithFrame: s_rc] retain];           \
391     [o_checkbox setFont:[NSFont systemFontOfSize:0]];                       \
392     [o_checkbox setButtonType: NSSwitchButton];                             \
393     [o_checkbox setImagePosition: position];                                \
394     [o_checkbox setIntValue: init_value];                                   \
395     [o_checkbox setTitle: label];                                           \
396     [o_checkbox setToolTip: tooltip];                                       \
397     [o_checkbox sizeToFit];                                                 \
398 }
399
400 @implementation VLCConfigControl
401 - (id)initWithFrame: (NSRect)frame
402 {
403     return [self initWithFrame: frame
404                     item: nil];
405 }
406
407 - (id)initWithFrame: (NSRect)frame
408         item: (module_config_t *)_p_item
409 {
410     self = [super initWithFrame: frame];
411
412     if( self != nil )
413     {
414         p_item = _p_item;
415         psz_name = p_item->psz_name;
416         o_label = NULL;
417         i_type = p_item->i_type;
418         i_view_type = 0;
419         b_advanced = p_item->b_advanced;
420         [self setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin ];
421     }
422     return (self);
423 }
424
425 - (void)setYPos:(int)i_yPos
426 {
427     NSRect frame = [self frame];
428     frame.origin.y = i_yPos;
429     [self setFrame:frame];
430 }
431
432 - (void)dealloc
433 {
434     if( o_label ) [o_label release];
435     free( psz_name );
436     [super dealloc];
437 }
438
439 + (int)calcVerticalMargin: (int)i_curItem lastItem: (int)i_lastItem
440 {
441     int i_margin;
442     switch( i_curItem )
443     {
444     case CONFIG_ITEM_STRING:
445     case CONFIG_ITEM_PASSWORD:
446         switch( i_lastItem )
447         {
448         case CONFIG_ITEM_STRING:
449         case CONFIG_ITEM_PASSWORD:
450             i_margin = 8;
451             break;
452         case CONFIG_ITEM_STRING_LIST:
453             i_margin = 7;
454             break;
455         case CONFIG_ITEM_FILE:
456             i_margin = 8;
457             break;
458         case CONFIG_ITEM_MODULE:
459             i_margin = 4;
460             break;
461         case CONFIG_ITEM_INTEGER:
462             i_margin = 7;
463             break;
464         case CONFIG_ITEM_RANGED_INTEGER:
465             i_margin = 5;
466             break;
467         case CONFIG_ITEM_BOOL:
468             i_margin = 7;
469             break;
470         case CONFIG_ITEM_KEY_AFTER_10_3:
471             i_margin = 6;
472             break;
473         case CONFIG_ITEM_MODULE_LIST:
474             i_margin = 8;
475             break;
476         default:
477             i_margin = 20;
478             break;
479         }
480         break;
481     case CONFIG_ITEM_STRING_LIST:
482         switch( i_lastItem )
483         {
484         case CONFIG_ITEM_STRING:
485         case CONFIG_ITEM_PASSWORD:
486             i_margin = 8;
487             break;
488         case CONFIG_ITEM_STRING_LIST:
489             i_margin = 7;
490             break;
491         case CONFIG_ITEM_FILE:
492             i_margin = 6;
493             break;
494         case CONFIG_ITEM_MODULE:
495             i_margin = 4;
496             break;
497         case CONFIG_ITEM_INTEGER:
498             i_margin = 7;
499             break;
500         case CONFIG_ITEM_RANGED_INTEGER:
501             i_margin = 5;
502             break;
503         case CONFIG_ITEM_BOOL:
504             i_margin = 7;
505             break;
506         case CONFIG_ITEM_KEY_AFTER_10_3:
507             i_margin = 6;
508             break;
509         case CONFIG_ITEM_MODULE_LIST:
510             i_margin = 8;
511             break;
512         default:
513             i_margin = 20;
514             break;
515         }
516         break;
517     case CONFIG_ITEM_FILE:
518         switch( i_lastItem )
519         {
520         case CONFIG_ITEM_STRING:
521         case CONFIG_ITEM_PASSWORD:
522             i_margin = 13;
523             break;
524         case CONFIG_ITEM_STRING_LIST:
525             i_margin = 10;
526             break;
527         case CONFIG_ITEM_FILE:
528             i_margin = 9;
529             break;
530         case CONFIG_ITEM_MODULE:
531             i_margin = 9;
532             break;
533         case CONFIG_ITEM_INTEGER:
534             i_margin = 10;
535             break;
536         case CONFIG_ITEM_RANGED_INTEGER:
537             i_margin = 8;
538             break;
539         case CONFIG_ITEM_BOOL:
540             i_margin = 10;
541             break;
542         case CONFIG_ITEM_KEY_AFTER_10_3:
543             i_margin = 9;
544             break;
545         case CONFIG_ITEM_MODULE_LIST:
546             i_margin = 11;
547             break;
548         default:
549             i_margin = 23;
550             break;
551         }
552         break;
553     case CONFIG_ITEM_MODULE:
554         switch( i_lastItem )
555         {
556         case CONFIG_ITEM_STRING:
557         case CONFIG_ITEM_PASSWORD:
558             i_margin = 8;
559             break;
560         case CONFIG_ITEM_STRING_LIST:
561             i_margin = 7;
562             break;
563         case CONFIG_ITEM_FILE:
564             i_margin = 6;
565             break;
566         case CONFIG_ITEM_MODULE:
567             i_margin = 5;
568             break;
569         case CONFIG_ITEM_INTEGER:
570             i_margin = 7;
571             break;
572         case CONFIG_ITEM_RANGED_INTEGER:
573             i_margin = 6;
574             break;
575         case CONFIG_ITEM_BOOL:
576             i_margin = 8;
577             break;
578         case CONFIG_ITEM_KEY_AFTER_10_3:
579             i_margin = 7;
580             break;
581         case CONFIG_ITEM_MODULE_LIST:
582             i_margin = 9;
583             break;
584         default:
585             i_margin = 20;
586             break;
587         }
588         break;
589     case CONFIG_ITEM_INTEGER:
590         switch( i_lastItem )
591         {
592         case CONFIG_ITEM_STRING:
593         case CONFIG_ITEM_PASSWORD:
594             i_margin = 8;
595             break;
596         case CONFIG_ITEM_STRING_LIST:
597             i_margin = 7;
598             break;
599         case CONFIG_ITEM_FILE:
600             i_margin = 6;
601             break;
602         case CONFIG_ITEM_MODULE:
603             i_margin = 4;
604             break;
605         case CONFIG_ITEM_INTEGER:
606             i_margin = 7;
607             break;
608         case CONFIG_ITEM_RANGED_INTEGER:
609             i_margin = 5;
610             break;
611         case CONFIG_ITEM_BOOL:
612             i_margin = 7;
613             break;
614         case CONFIG_ITEM_KEY_AFTER_10_3:
615             i_margin = 6;
616             break;
617         case CONFIG_ITEM_MODULE_LIST:
618             i_margin = 8;
619             break;
620         default:
621             i_margin = 20;
622             break;
623         }
624         break;
625     case CONFIG_ITEM_RANGED_INTEGER:
626         switch( i_lastItem )
627         {
628         case CONFIG_ITEM_STRING:
629         case CONFIG_ITEM_PASSWORD:
630             i_margin = 8;
631             break;
632         case CONFIG_ITEM_STRING_LIST:
633             i_margin = 7;
634             break;
635         case CONFIG_ITEM_FILE:
636             i_margin = 8;
637             break;
638         case CONFIG_ITEM_MODULE:
639             i_margin = 4;
640             break;
641         case CONFIG_ITEM_INTEGER:
642             i_margin = 7;
643             break;
644         case CONFIG_ITEM_RANGED_INTEGER:
645             i_margin = 5;
646             break;
647         case CONFIG_ITEM_BOOL:
648             i_margin = 7;
649             break;
650         case CONFIG_ITEM_KEY_AFTER_10_3:
651             i_margin = 6;
652             break;
653         case CONFIG_ITEM_MODULE_LIST:
654             i_margin = 8;
655             break;
656         default:
657             i_margin = 20;
658             break;
659         }
660         break;
661     case CONFIG_ITEM_BOOL:
662         switch( i_lastItem )
663         {
664         case CONFIG_ITEM_STRING:
665         case CONFIG_ITEM_PASSWORD:
666             i_margin = 10;
667             break;
668         case CONFIG_ITEM_STRING_LIST:
669             i_margin = 9;
670             break;
671         case CONFIG_ITEM_FILE:
672             i_margin = 8;
673             break;
674         case CONFIG_ITEM_MODULE:
675             i_margin = 6;
676             break;
677         case CONFIG_ITEM_INTEGER:
678             i_margin = 9;
679             break;
680         case CONFIG_ITEM_RANGED_INTEGER:
681             i_margin = 7;
682             break;
683         case CONFIG_ITEM_BOOL:
684             i_margin = 7;
685             break;
686         case CONFIG_ITEM_KEY_AFTER_10_3:
687             i_margin = 5;
688             break;
689         case CONFIG_ITEM_MODULE_LIST:
690             i_margin = 10;
691             break;
692         default:
693             i_margin = 20;
694             break;
695         }
696         break;
697     case CONFIG_ITEM_KEY_AFTER_10_3:
698         switch( i_lastItem )
699         {
700         case CONFIG_ITEM_STRING:
701         case CONFIG_ITEM_PASSWORD:
702             i_margin = 8;
703             break;
704         case CONFIG_ITEM_STRING_LIST:
705             i_margin = 7;
706             break;
707         case CONFIG_ITEM_FILE:
708             i_margin = 6;
709             break;
710         case CONFIG_ITEM_MODULE:
711             i_margin = 6;
712             break;
713         case CONFIG_ITEM_INTEGER:
714             i_margin = 7;
715             break;
716         case CONFIG_ITEM_RANGED_INTEGER:
717             i_margin = 5;
718             break;
719         case CONFIG_ITEM_BOOL:
720             i_margin = 7;
721             break;
722         case CONFIG_ITEM_KEY_AFTER_10_3:
723             i_margin = 8;
724             break;
725         case CONFIG_ITEM_MODULE_LIST:
726             i_margin = 10;
727             break;
728         default:
729             i_margin = 20;
730             break;
731         }
732         break;
733     case CONFIG_ITEM_MODULE_LIST:
734         switch( i_lastItem )
735         {
736         case CONFIG_ITEM_STRING:
737         case CONFIG_ITEM_PASSWORD:
738             i_margin = 10;
739             break;
740         case CONFIG_ITEM_STRING_LIST:
741             i_margin = 7;
742             break;
743         case CONFIG_ITEM_FILE:
744             i_margin = 6;
745             break;
746         case CONFIG_ITEM_MODULE:
747             i_margin = 6;
748             break;
749         case CONFIG_ITEM_INTEGER:
750             i_margin = 9;
751             break;
752         case CONFIG_ITEM_RANGED_INTEGER:
753             i_margin = 5;
754             break;
755         case CONFIG_ITEM_BOOL:
756             i_margin = 7;
757             break;
758         case CONFIG_ITEM_KEY_AFTER_10_3:
759             i_margin = 5;
760             break;
761         case CONFIG_ITEM_MODULE_LIST:
762             i_margin = 8;
763             break;
764         default:
765             i_margin = 20;
766             break;
767         }
768         break;
769     default:
770         i_margin = 20;
771         break;
772     }
773     return i_margin;
774 }
775
776 + (VLCConfigControl *)newControl: (module_config_t *)_p_item
777                       withView: (NSView *)o_parent_view
778 {
779     VLCConfigControl *p_control = NULL;
780
781     switch( _p_item->i_type )
782     {
783     case CONFIG_ITEM_STRING:
784     case CONFIG_ITEM_PASSWORD:
785         if( !_p_item->i_list )
786         {
787             p_control = [[StringConfigControl alloc]
788                     initWithItem: _p_item
789                     withView: o_parent_view];
790         }
791         else
792         {
793             p_control = [[StringListConfigControl alloc]
794                     initWithItem: _p_item
795                     withView: o_parent_view];
796         }
797         break;
798     case CONFIG_ITEM_FILE:
799     case CONFIG_ITEM_DIRECTORY:
800         p_control = [[FileConfigControl alloc]
801                     initWithItem: _p_item
802                     withView: o_parent_view];
803         break;
804     case CONFIG_ITEM_MODULE:
805     case CONFIG_ITEM_MODULE_CAT:
806         p_control = [[ModuleConfigControl alloc]
807                     initWithItem: _p_item
808                     withView: o_parent_view];
809         break;
810     case CONFIG_ITEM_INTEGER:
811         if( _p_item->i_list )
812         {
813             p_control = [[IntegerListConfigControl alloc]
814                         initWithItem: _p_item
815                         withView: o_parent_view];
816         }
817         else if( _p_item->min.i != 0 || _p_item->max.i != 0 )
818         {
819             p_control = [[RangedIntegerConfigControl alloc]
820                         initWithItem: _p_item
821                         withView: o_parent_view];
822         }
823         else
824         {
825             p_control = [[IntegerConfigControl alloc]
826                         initWithItem: _p_item
827                         withView: o_parent_view];
828         }
829         break;
830     case CONFIG_ITEM_BOOL:
831         p_control = [[BoolConfigControl alloc]
832                     initWithItem: _p_item
833                     withView: o_parent_view];
834         break;
835     case CONFIG_ITEM_FLOAT:
836         if( _p_item->min.f != 0 || _p_item->max.f != 0 )
837         {
838             p_control = [[RangedFloatConfigControl alloc]
839                         initWithItem: _p_item
840                         withView: o_parent_view];
841         }
842         else
843         {
844             p_control = [[FloatConfigControl alloc]
845                         initWithItem: _p_item
846                         withView: o_parent_view];
847         }
848         break;
849     case CONFIG_ITEM_KEY:
850         p_control = [[KeyConfigControl alloc]
851                         initWithItem: _p_item
852                         withView: o_parent_view];
853         break;
854     case CONFIG_ITEM_MODULE_LIST:
855     case CONFIG_ITEM_MODULE_LIST_CAT:
856         p_control = [[ModuleListConfigControl alloc]
857                     initWithItem: _p_item
858                     withView: o_parent_view];
859         break;
860     default:
861         break;
862     }
863     return p_control;
864 }
865
866 - (NSString *)name
867 {
868     return [[VLCMain sharedInstance] localizedString: psz_name];
869 }
870
871 - (int)type
872 {
873     return i_type;
874 }
875
876 - (int)viewType
877 {
878     return i_view_type;
879 }
880
881 - (BOOL)isAdvanced
882 {
883     return b_advanced;
884 }
885
886 - (int)intValue
887 {
888     return 0;
889 }
890
891 - (float)floatValue
892 {
893     return 0;
894 }
895
896 - (char *)stringValue
897 {
898     return NULL;
899 }
900
901 - (void)applyChanges
902 {
903     vlc_value_t val;
904     switch( p_item->i_type )
905     {
906     case CONFIG_ITEM_STRING:
907     case CONFIG_ITEM_PASSWORD:
908     case CONFIG_ITEM_FILE:
909     case CONFIG_ITEM_DIRECTORY:
910     case CONFIG_ITEM_MODULE:
911     case CONFIG_ITEM_MODULE_LIST:
912     case CONFIG_ITEM_MODULE_LIST_CAT:
913         config_PutPsz( VLCIntf, psz_name, [self stringValue] );
914         break;
915     case CONFIG_ITEM_KEY:
916         /* So you don't need to restart to have the changes take effect */
917         val.i_int = [self intValue];
918         var_Set( VLCIntf->p_libvlc, psz_name, val );
919     case CONFIG_ITEM_INTEGER:
920     case CONFIG_ITEM_BOOL:
921         config_PutInt( VLCIntf, psz_name, [self intValue] );
922         break;
923     case CONFIG_ITEM_FLOAT:
924         config_PutFloat( VLCIntf, psz_name, [self floatValue] );
925         break;
926     }
927 }
928
929 - (void)resetValues
930 {
931 }
932
933 - (int)labelSize
934 {
935     return [o_label frame].size.width;
936 }
937
938 - (void) alignWithXPosition:(int)i_xPos;
939 {
940     /* FIXME: not implemented atm, but created to shut up the warning
941      * about "method definition not found" -- FK @ 7/24/05 */
942 }
943 @end
944
945 @implementation StringConfigControl
946 - (id) initWithItem: (module_config_t *)_p_item
947            withView: (NSView *)o_parent_view
948 {
949     NSRect mainFrame = [o_parent_view frame];
950     NSString *o_labelString, *o_textfieldString, *o_textfieldTooltip;
951     mainFrame.size.height = 22;
952     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN;
953     mainFrame.origin.x = LEFTMARGIN;
954     mainFrame.origin.y = 0;
955
956     if( [super initWithFrame: mainFrame item: _p_item] != nil )
957     {
958         if( p_item->i_type == CONFIG_ITEM_PASSWORD )
959             i_view_type = CONFIG_ITEM_PASSWORD;
960         else
961             i_view_type = CONFIG_ITEM_STRING;
962
963         o_textfieldTooltip = [[VLCMain sharedInstance] wrapString:
964                               [[VLCMain sharedInstance] localizedString: (char *)p_item->psz_longtext]
965                                                           toWidth: PREFS_WRAP];
966
967         /* add the label */
968         if( p_item->psz_text )
969             o_labelString = [[VLCMain sharedInstance]
970                                 localizedString: (char *)p_item->psz_text];
971         else
972             o_labelString = [NSString stringWithString:@""];
973         ADD_LABEL( o_label, mainFrame, 0, -3, o_labelString, o_textfieldTooltip )
974         [o_label setAutoresizingMask:NSViewNotSizable ];
975         [self addSubview: o_label];
976
977         /* build the textfield */
978         if( p_item->value.psz )
979             o_textfieldString = [[VLCMain sharedInstance]
980                                     localizedString: (char *)p_item->value.psz];
981         else
982             o_textfieldString = [NSString stringWithString: @""];
983         if( p_item->i_type == CONFIG_ITEM_PASSWORD )
984         {
985             ADD_SECURETEXTFIELD( o_textfield, mainFrame, [o_label frame].size.width + 2,
986                           0, mainFrame.size.width - [o_label frame].size.width -
987                           2, o_textfieldTooltip, o_textfieldString )
988         }
989         else
990         {
991             ADD_TEXTFIELD( o_textfield, mainFrame, [o_label frame].size.width + 2,
992                             0, mainFrame.size.width - [o_label frame].size.width -
993                             2, o_textfieldTooltip, o_textfieldString )
994         }
995         [o_textfield setAutoresizingMask:NSViewWidthSizable ];
996
997         [self addSubview: o_textfield];
998     }
999     return self;
1000 }
1001
1002 - (void) alignWithXPosition:(int)i_xPos
1003 {
1004     NSRect frame;
1005     NSRect superFrame = [self frame];
1006     frame = [o_label frame];
1007     frame.origin.x = i_xPos - frame.size.width - 3;
1008     [o_label setFrame:frame];
1009
1010     frame = [o_textfield frame];
1011     frame.origin.x = i_xPos + 2;
1012     frame.size.width = superFrame.size.width - frame.origin.x - 1;
1013     [o_textfield setFrame:frame];
1014 }
1015
1016 - (void)dealloc
1017 {
1018     [o_textfield release];
1019     [super dealloc];
1020 }
1021
1022 - (char *)stringValue
1023 {
1024     return [[VLCMain sharedInstance] delocalizeString:
1025                         [o_textfield stringValue]];
1026 }
1027
1028 - (void)resetValues
1029 {
1030     NSString *o_textfieldString;
1031     char *psz_value = config_GetPsz( VLCIntf, p_item->psz_name );
1032     if( psz_value )
1033         o_textfieldString = [[VLCMain sharedInstance]
1034                                 localizedString: psz_value];
1035     else
1036         o_textfieldString = [NSString stringWithString: @""];
1037     free( psz_value );
1038     [super resetValues];
1039 }
1040 @end
1041
1042 @implementation StringListConfigControl
1043 - (id) initWithItem: (module_config_t *)_p_item
1044            withView: (NSView *)o_parent_view
1045 {
1046     NSRect mainFrame = [o_parent_view frame];
1047     NSString *o_labelString, *o_textfieldTooltip;
1048     mainFrame.size.height = 22;
1049     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1;
1050     mainFrame.origin.x = LEFTMARGIN;
1051     mainFrame.origin.y = 0;
1052
1053     if( [super initWithFrame: mainFrame item: _p_item] != nil )
1054     {
1055         int i_index;
1056         i_view_type = CONFIG_ITEM_STRING_LIST;
1057
1058         o_textfieldTooltip = [[VLCMain sharedInstance] wrapString:
1059                               [[VLCMain sharedInstance]
1060                                localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];
1061
1062         /* add the label */
1063         if( p_item->psz_text )
1064             o_labelString = [[VLCMain sharedInstance]
1065                                 localizedString: (char *)p_item->psz_text];
1066         else
1067             o_labelString = [NSString stringWithString:@""];
1068         ADD_LABEL( o_label, mainFrame, 0, -3, o_labelString, o_textfieldTooltip )
1069         [o_label setAutoresizingMask:NSViewNotSizable ];
1070         [self addSubview: o_label];
1071
1072         /* build the textfield */
1073         ADD_COMBO( o_combo, mainFrame, [o_label frame].size.width,
1074             -2, 0, o_textfieldTooltip )
1075         [o_combo setAutoresizingMask:NSViewWidthSizable ];
1076         for( i_index = 0; i_index < p_item->i_list; i_index++ )
1077         {
1078             if( !p_item->value.psz && !p_item->ppsz_list[i_index] )
1079                 [o_combo selectItemAtIndex: i_index];
1080             else if( p_item->value.psz && p_item->ppsz_list[i_index] &&
1081                 !strcmp( p_item->value.psz, p_item->ppsz_list[i_index] ) )
1082                 [o_combo selectItemAtIndex: i_index];
1083        }
1084         [self addSubview: o_combo];
1085     }
1086     return self;
1087 }
1088
1089 - (void) alignWithXPosition:(int)i_xPos
1090 {
1091     NSRect frame;
1092     NSRect superFrame = [self frame];
1093     frame = [o_label frame];
1094     frame.origin.x = i_xPos - frame.size.width - 3;
1095     [o_label setFrame:frame];
1096
1097     frame = [o_combo frame];
1098     frame.origin.x = i_xPos + 2;
1099     frame.size.width = superFrame.size.width - frame.origin.x + 2;
1100     [o_combo setFrame:frame];
1101 }
1102
1103 - (void)dealloc
1104 {
1105     [o_combo release];
1106     [super dealloc];
1107 }
1108
1109 - (char *)stringValue
1110 {
1111     if( [o_combo indexOfSelectedItem] >= 0 )
1112         return strdup( p_item->ppsz_list[[o_combo indexOfSelectedItem]] );
1113     else
1114         return strdup( [[VLCMain sharedInstance]
1115                             delocalizeString: [o_combo stringValue]] );
1116 }
1117
1118 - (void)resetValues
1119 {
1120     int i_index;
1121     [o_combo reloadData];
1122     char *psz_value = config_GetPsz( VLCIntf, p_item->psz_name );
1123
1124     for( i_index = 0; i_index < p_item->i_list; i_index++ )
1125     {
1126         if( !psz_value && !p_item->ppsz_list[i_index] )
1127             [o_combo selectItemAtIndex: i_index];
1128         else if( psz_value && p_item->ppsz_list[i_index] &&
1129             !strcmp( psz_value, p_item->ppsz_list[i_index] ) )
1130             [o_combo selectItemAtIndex: i_index];
1131     }
1132
1133     free( psz_value );
1134     [super resetValues];
1135 }
1136 @end
1137
1138 @implementation StringListConfigControl (NSComboBoxDataSource)
1139 - (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox
1140 {
1141         return p_item->i_list;
1142 }
1143
1144 - (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)i_index
1145 {
1146     if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
1147     {
1148         return [[VLCMain sharedInstance]
1149                     localizedString: (char *)p_item->ppsz_list_text[i_index]];
1150     } else return [[VLCMain sharedInstance]
1151                     localizedString: (char *)p_item->ppsz_list[i_index]];
1152 }
1153 @end
1154
1155 @implementation FileConfigControl
1156 - (id) initWithItem: (module_config_t *)_p_item
1157            withView: (NSView *)o_parent_view
1158 {
1159     NSRect mainFrame = [o_parent_view frame];
1160     NSString *o_labelString, *o_itemTooltip, *o_textfieldString;
1161     mainFrame.size.height = 46;
1162     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN;
1163     mainFrame.origin.x = LEFTMARGIN;
1164     mainFrame.origin.y = 0;
1165
1166     if( [super initWithFrame: mainFrame item: _p_item] != nil )
1167     {
1168         i_view_type = CONFIG_ITEM_FILE;
1169
1170         o_itemTooltip = [[VLCMain sharedInstance]
1171                            wrapString: [[VLCMain sharedInstance]
1172                                         localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];
1173
1174         /* is it a directory */
1175         b_directory = ( [self type] == CONFIG_ITEM_DIRECTORY ) ? YES : NO;
1176
1177         /* add the label */
1178         if( p_item->psz_text )
1179             o_labelString = [[VLCMain sharedInstance]
1180                                 localizedString: (char *)p_item->psz_text];
1181         else
1182             o_labelString = [NSString stringWithString:@""];
1183         ADD_LABEL( o_label, mainFrame, 0, 3, o_labelString, o_itemTooltip )
1184         [o_label setAutoresizingMask:NSViewNotSizable ];
1185         [self addSubview: o_label];
1186
1187         /* build the button */
1188         ADD_RIGHT_BUTTON( o_button, mainFrame, 0, 0, o_itemTooltip,
1189                             _NS("Browse...") )
1190         [o_button setAutoresizingMask:NSViewMinXMargin ];
1191         [self addSubview: o_button];
1192
1193         /* build the textfield */
1194         if( p_item->value.psz )
1195             o_textfieldString = [NSString stringWithFormat: @"%s", (char *)p_item->value.psz];
1196         else
1197             o_textfieldString = [NSString stringWithString: @""];
1198         ADD_TEXTFIELD( o_textfield, mainFrame, 12, 2, mainFrame.size.width -
1199                         8 - [o_button frame].size.width,
1200                         o_itemTooltip, o_textfieldString )
1201         [o_textfield setAutoresizingMask:NSViewWidthSizable ];
1202         [self addSubview: o_textfield];
1203     }
1204     return self;
1205 }
1206
1207 - (void) alignWithXPosition:(int)i_xPos
1208 {
1209     ;
1210 }
1211
1212 - (void)dealloc
1213 {
1214     [o_textfield release];
1215     [o_button release];
1216     [super dealloc];
1217 }
1218
1219 - (IBAction)openFileDialog: (id)sender
1220 {
1221     NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
1222
1223     [o_open_panel setTitle: (b_directory)?
1224         _NS("Select a directory"):_NS("Select a file")];
1225     [o_open_panel setPrompt: _NS("Select")];
1226     [o_open_panel setAllowsMultipleSelection: NO];
1227     [o_open_panel setCanChooseFiles: !b_directory];
1228     [o_open_panel setCanChooseDirectories: b_directory];
1229     [o_open_panel beginSheetForDirectory:nil
1230         file:nil
1231         types:nil
1232         modalForWindow:[sender window]
1233         modalDelegate: self
1234         didEndSelector: @selector(pathChosenInPanel:
1235                         withReturn:
1236                         contextInfo:)
1237         contextInfo: nil];
1238 }
1239
1240 - (void)pathChosenInPanel:(NSOpenPanel *)o_sheet
1241     withReturn:(int)i_return_code contextInfo:(void  *)o_context_info
1242 {
1243     if( i_return_code == NSOKButton )
1244     {
1245         NSString *o_path = [[o_sheet filenames] objectAtIndex: 0];
1246         [o_textfield setStringValue: o_path];
1247     }
1248 }
1249
1250 - (char *)stringValue
1251 {
1252     if( [[o_textfield stringValue] length] != 0)
1253         return strdup( [[o_textfield stringValue] fileSystemRepresentation] );
1254     else
1255         return NULL;
1256 }
1257
1258 -(void)resetValues
1259 {
1260     NSString *o_textfieldString;
1261     char *psz_value = config_GetPsz( VLCIntf, p_item->psz_name );
1262     if( psz_value )
1263         o_textfieldString = [NSString stringWithFormat: @"%s", psz_value];
1264     else
1265         o_textfieldString = [NSString stringWithString: @""];
1266
1267     free(psz_value);
1268     [super resetValues];
1269 }
1270 @end
1271
1272 @implementation ModuleConfigControl
1273 - (id) initWithItem: (module_config_t *)_p_item
1274            withView: (NSView *)o_parent_view
1275 {
1276     NSRect mainFrame = [o_parent_view frame];
1277     NSString *o_labelString, *o_popupTooltip;
1278     mainFrame.size.height = 22;
1279     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1;
1280     mainFrame.origin.x = LEFTMARGIN;
1281     mainFrame.origin.y = 0;
1282
1283     if( [super initWithFrame: mainFrame item: _p_item] != nil )
1284     {
1285         i_view_type = CONFIG_ITEM_MODULE;
1286
1287         o_popupTooltip = [[VLCMain sharedInstance] wrapString:
1288                           [[VLCMain sharedInstance]
1289                            localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];
1290
1291         /* add the label */
1292         if( p_item->psz_text )
1293             o_labelString = [[VLCMain sharedInstance]
1294                                 localizedString: (char *)p_item->psz_text];
1295         else
1296             o_labelString = [NSString stringWithString:@""];
1297         ADD_LABEL( o_label, mainFrame, 0, -1, o_labelString, o_popupTooltip )
1298         [o_label setAutoresizingMask:NSViewNotSizable ];
1299         [self addSubview: o_label];
1300
1301         /* build the popup */
1302         ADD_POPUP( o_popup, mainFrame, [o_label frame].size.width,
1303             -2, 0, o_popupTooltip )
1304         [o_popup setAutoresizingMask:NSViewWidthSizable ];
1305         [o_popup addItemWithTitle: _NS("Default")];
1306         [[o_popup lastItem] setTag: -1];
1307         [o_popup selectItem: [o_popup lastItem]];
1308
1309         [self resetValues];
1310         [self addSubview: o_popup];
1311     }
1312     return self;
1313 }
1314
1315 - (void) alignWithXPosition:(int)i_xPos
1316 {
1317     NSRect frame;
1318     NSRect superFrame = [self frame];
1319     frame = [o_label frame];
1320     frame.origin.x = i_xPos - frame.size.width - 3;
1321     [o_label setFrame:frame];
1322
1323     frame = [o_popup frame];
1324     frame.origin.x = i_xPos - 1;
1325     frame.size.width = superFrame.size.width - frame.origin.x + 2;
1326     [o_popup setFrame:frame];
1327 }
1328
1329 - (void)dealloc
1330 {
1331     [o_popup release];
1332     [super dealloc];
1333 }
1334
1335 - (char *)stringValue
1336 {
1337     NSString *newval = [o_popup titleOfSelectedItem];
1338     char *returnval = NULL;
1339     size_t i_module_index;
1340     module_t *p_parser, **p_list;
1341
1342     p_list = module_list_get( NULL );
1343     for( i_module_index = 0; p_list[i_module_index]; i_module_index++ )
1344     {
1345         p_parser = p_list[i_module_index];
1346
1347         if( p_item->i_type == CONFIG_ITEM_MODULE )
1348         {
1349             if( module_provides( p_parser, p_item->psz_type ) )
1350             {
1351                 NSString *o_description = [[VLCMain sharedInstance]
1352                     localizedString: module_GetLongName( p_parser )];
1353                 if( [newval isEqualToString: o_description] )
1354                 {
1355                     returnval = strdup( module_get_object( p_parser ));
1356                     break;
1357                 }
1358             }
1359         }
1360         else
1361         {
1362             int i;
1363
1364             if( module_is_main( p_parser) )
1365                 continue;
1366             unsigned int confsize, unused;
1367             module_config_get( p_parser, &confsize );
1368             for ( i = 0; i < confsize; i++ )
1369             {
1370                 module_config_t *p_config = module_config_get( p_parser, &unused ) + i;
1371                 /* Hack: required subcategory is stored in i_min */
1372                 if( p_config->i_type == CONFIG_SUBCATEGORY &&
1373                     p_config->value.i == p_item->min.i )
1374                 {
1375                     NSString *o_description = [[VLCMain sharedInstance]
1376                         localizedString: module_GetLongName( p_parser )];
1377                     if( [newval isEqualToString: o_description] )
1378                     {
1379                         returnval = strdup(module_get_object( p_parser ));
1380                         break;
1381                     }
1382                 }
1383             }
1384         }
1385     }
1386     module_list_free( p_list );
1387     return returnval;
1388 }
1389
1390 -(void)resetValues
1391 {
1392     /* build a list of available modules */
1393     size_t i_index;
1394     module_t *p_parser, **p_list;
1395
1396     p_list = module_list_get( NULL );
1397     for( i_index = 0; p_list[i_index]; i_index++ )
1398     {
1399         p_parser = p_list[i_index];
1400
1401         if( p_item->i_type == CONFIG_ITEM_MODULE )
1402         {
1403             if( module_provides( p_parser, p_item->psz_type ) )
1404             {
1405                 NSString *o_description = [[VLCMain sharedInstance]
1406                     localizedString: module_GetLongName( p_parser )];
1407                 [o_popup addItemWithTitle: o_description];
1408                 char *psz_value = config_GetPsz( VLCIntf, p_item->psz_name );
1409
1410                 if( psz_value &&
1411                     !strcmp( psz_value, module_get_object( p_parser ) ) )
1412                     [o_popup selectItem:[o_popup lastItem]];
1413
1414                 free(psz_value);
1415             }
1416         }
1417         else
1418         {
1419             int i;
1420
1421             if( module_is_main( p_parser ) )
1422                 continue;
1423             unsigned int confsize;
1424             unsigned int unused;
1425             module_config_t *p_configlist = module_config_get( p_parser, &confsize );
1426             for ( i = 0; i < confsize; i++ )
1427             {
1428                 module_config_t *p_config = &p_configlist[i];
1429                 /* Hack: required subcategory is stored in i_min */
1430                 if( p_config->i_type == CONFIG_SUBCATEGORY &&
1431                     config_GetInt( VLCIntf, p_item->psz_name) == p_item->min.i )
1432                 {
1433                     NSString *o_description = [[VLCMain sharedInstance]
1434                         localizedString: module_GetLongName( p_parser )];
1435                     [o_popup addItemWithTitle: o_description];
1436                     char *psz_value = config_GetPsz( VLCIntf, p_item->psz_name );
1437
1438                     if( psz_value && !strcmp(psz_value,
1439                                             module_get_object( p_parser )) )
1440                         [o_popup selectItem:[o_popup lastItem]];
1441
1442                     free( psz_value );
1443                 }
1444             }
1445             module_config_free( p_configlist );
1446         }
1447     }
1448     module_list_free( p_list );
1449     [super resetValues];
1450 }
1451 @end
1452
1453 @implementation IntegerConfigControl
1454 - (id) initWithItem: (module_config_t *)_p_item
1455            withView: (NSView *)o_parent_view
1456 {
1457     NSRect mainFrame = [o_parent_view frame];
1458     NSString *o_labelString, *o_tooltip;
1459     mainFrame.size.height = 23;
1460     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1;
1461     mainFrame.origin.x = LEFTMARGIN;
1462     mainFrame.origin.y = 0;
1463
1464     if( [super initWithFrame: mainFrame item: _p_item] != nil )
1465     {
1466         i_view_type = CONFIG_ITEM_INTEGER;
1467
1468         o_tooltip = [[VLCMain sharedInstance] wrapString:
1469             [[VLCMain sharedInstance]
1470                 localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];
1471
1472         /* add the label */
1473         if( p_item->psz_text )
1474             o_labelString = [[VLCMain sharedInstance]
1475                                 localizedString: (char *)p_item->psz_text];
1476         else
1477             o_labelString = [NSString stringWithString:@""];
1478         ADD_LABEL( o_label, mainFrame, 0, -3, o_labelString, o_tooltip )
1479         [o_label setAutoresizingMask:NSViewNotSizable ];
1480         [self addSubview: o_label];
1481
1482         /* build the stepper */
1483         ADD_STEPPER( o_stepper, mainFrame, mainFrame.size.width - 19,
1484             0, o_tooltip, -100000, 100000)
1485         [o_stepper setIntValue: p_item->value.i];
1486         [o_stepper setAutoresizingMask:NSViewMaxXMargin ];
1487         [self addSubview: o_stepper];
1488
1489         ADD_TEXTFIELD( o_textfield, mainFrame, mainFrame.size.width - 19 - 52,
1490             1, 49, o_tooltip, @"" )
1491         [o_textfield setIntValue: p_item->value.i];
1492         [o_textfield setDelegate: self];
1493         [[NSNotificationCenter defaultCenter] addObserver: self
1494             selector: @selector(textfieldChanged:)
1495             name: NSControlTextDidChangeNotification
1496             object: o_textfield];
1497         [o_textfield setAutoresizingMask:NSViewMaxXMargin ];
1498         [self addSubview: o_textfield];
1499     }
1500     return self;
1501 }
1502
1503 - (void) alignWithXPosition:(int)i_xPos
1504 {
1505     NSRect frame;
1506     frame = [o_label frame];
1507     frame.origin.x = i_xPos - frame.size.width - 3;
1508     [o_label setFrame:frame];
1509
1510     frame = [o_textfield frame];
1511     frame.origin.x = i_xPos + 2;
1512     [o_textfield setFrame:frame];
1513
1514     frame = [o_stepper frame];
1515     frame.origin.x = i_xPos + [o_textfield frame].size.width + 5;
1516     [o_stepper setFrame:frame];
1517 }
1518
1519 - (void)dealloc
1520 {
1521     [o_stepper release];
1522     [o_textfield release];
1523     [super dealloc];
1524 }
1525
1526 - (IBAction)stepperChanged:(id)sender
1527 {
1528     [o_textfield setIntValue: [o_stepper intValue]];
1529 }
1530
1531 - (void)textfieldChanged:(NSNotification *)o_notification
1532 {
1533     [o_stepper setIntValue: [o_textfield intValue]];
1534 }
1535
1536 - (int)intValue
1537 {
1538     return [o_textfield intValue];
1539 }
1540
1541 -(void)resetValues
1542 {
1543     [o_textfield setIntValue: config_GetInt(VLCIntf, p_item->psz_name)];
1544     [super resetValues];
1545 }
1546
1547 @end
1548
1549 @implementation IntegerListConfigControl
1550
1551 - (id) initWithItem: (module_config_t *)_p_item
1552            withView: (NSView *)o_parent_view
1553 {
1554     NSRect mainFrame = [o_parent_view frame];
1555     NSString *o_labelString, *o_textfieldTooltip;
1556     mainFrame.size.height = 22;
1557     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1;
1558     mainFrame.origin.x = LEFTMARGIN;
1559     mainFrame.origin.y = 0;
1560
1561     if( [super initWithFrame: mainFrame item: _p_item] != nil )
1562     {
1563         int i_index;
1564         i_view_type = CONFIG_ITEM_STRING_LIST;
1565
1566         o_textfieldTooltip = [[VLCMain sharedInstance] wrapString:
1567                               [[VLCMain sharedInstance]
1568                                localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];        
1569
1570         /* add the label */
1571         if( p_item->psz_text )
1572             o_labelString = [[VLCMain sharedInstance]
1573                 localizedString: (char *)p_item->psz_text];
1574         else
1575             o_labelString = [NSString stringWithString:@""];
1576         ADD_LABEL( o_label, mainFrame, 0, -3, o_labelString, o_textfieldTooltip )
1577         [o_label setAutoresizingMask:NSViewNotSizable ];
1578         [self addSubview: o_label];
1579
1580         /* build the textfield */
1581         ADD_COMBO( o_combo, mainFrame, [o_label frame].size.width,
1582             -2, 0, o_textfieldTooltip )
1583         [o_combo setAutoresizingMask:NSViewWidthSizable ];
1584         for( i_index = 0; i_index < p_item->i_list; i_index++ )
1585         {
1586             if( p_item->value.i == p_item->pi_list[i_index] )
1587             {
1588                 [o_combo selectItemAtIndex: i_index];
1589             }
1590         }
1591         [self addSubview: o_combo];
1592     }
1593     return self;
1594 }
1595
1596 - (void) alignWithXPosition:(int)i_xPos
1597 {
1598     NSRect frame;
1599     NSRect superFrame = [self frame];
1600     frame = [o_label frame];
1601     frame.origin.x = i_xPos - frame.size.width - 3;
1602     [o_label setFrame:frame];
1603
1604     frame = [o_combo frame];
1605     frame.origin.x = i_xPos + 2;
1606     frame.size.width = superFrame.size.width - frame.origin.x + 2;
1607     [o_combo setFrame:frame];
1608 }
1609
1610 - (void)dealloc
1611 {
1612     [o_combo release];
1613     [super dealloc];
1614 }
1615
1616 - (int)intValue
1617 {
1618     if( [o_combo indexOfSelectedItem] >= 0 )
1619         return p_item->pi_list[[o_combo indexOfSelectedItem]];
1620     else
1621         return [o_combo intValue];
1622 }
1623
1624 -(void)resetValues
1625 {
1626     int i_index;
1627     [o_combo reloadData];
1628     for( i_index = 0; i_index < p_item->i_list; i_index++ )
1629     {
1630         if( config_GetInt( VLCIntf, p_item->psz_name) == p_item->pi_list[i_index] )
1631         {
1632             [o_combo selectItemAtIndex: i_index];
1633         }
1634     }
1635
1636 }
1637 @end
1638
1639 @implementation IntegerListConfigControl (NSComboBoxDataSource)
1640 - (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox
1641 {
1642     return p_item->i_list;
1643 }
1644
1645 - (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)i_index
1646 {
1647     if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
1648         return [[VLCMain sharedInstance]
1649                     localizedString: (char *)p_item->ppsz_list_text[i_index]];
1650     else
1651         return [NSString stringWithFormat: @"%i", p_item->pi_list[i_index]];
1652 }
1653 @end
1654
1655 @implementation RangedIntegerConfigControl
1656 - (id) initWithItem: (module_config_t *)_p_item
1657            withView: (NSView *)o_parent_view
1658 {
1659     NSRect mainFrame = [o_parent_view frame];
1660     NSString *o_labelString, *o_tooltip;
1661     mainFrame.size.height = 50;
1662     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN;
1663     mainFrame.origin.x = LEFTMARGIN;
1664     mainFrame.origin.y = 0;
1665
1666     if( [super initWithFrame: mainFrame item: _p_item] != nil )
1667     {
1668         i_view_type = CONFIG_ITEM_RANGED_INTEGER;
1669
1670         o_tooltip = [[VLCMain sharedInstance] wrapString:
1671                      [[VLCMain sharedInstance]
1672                       localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];
1673
1674         /* add the label */
1675         if( p_item->psz_text )
1676             o_labelString = [[VLCMain sharedInstance]
1677                                 localizedString: (char *)p_item->psz_text];
1678         else
1679             o_labelString = [NSString stringWithString:@""];
1680         ADD_LABEL( o_label, mainFrame, 0, -3, o_labelString, o_tooltip )
1681         [o_label setAutoresizingMask:NSViewNotSizable ];
1682         [self addSubview: o_label];
1683
1684         /* build the textfield */
1685         ADD_TEXTFIELD( o_textfield, mainFrame, [o_label frame].size.width + 2,
1686             28, 49, o_tooltip, @"" )
1687         [o_textfield setIntValue: p_item->value.i];
1688         [o_textfield setAutoresizingMask:NSViewMaxXMargin ];
1689         [o_textfield setDelegate: self];
1690         [[NSNotificationCenter defaultCenter] addObserver: self
1691             selector: @selector(textfieldChanged:)
1692             name: NSControlTextDidChangeNotification
1693             object: o_textfield];
1694         [self addSubview: o_textfield];
1695
1696         /* build the mintextfield */
1697         ADD_LABEL( o_textfield_min, mainFrame, 12, -30, @"-8888", @"" )
1698         [o_textfield_min setIntValue: p_item->min.i];
1699         [o_textfield_min setAutoresizingMask:NSViewMaxXMargin ];
1700         [o_textfield_min setAlignment:NSRightTextAlignment];
1701         [self addSubview: o_textfield_min];
1702
1703         /* build the maxtextfield */
1704         ADD_LABEL( o_textfield_max, mainFrame,
1705                     mainFrame.size.width - 31, -30, @"8888", @"" )
1706         [o_textfield_max setIntValue: p_item->max.i];
1707         [o_textfield_max setAutoresizingMask:NSViewMinXMargin ];
1708         [self addSubview: o_textfield_max];
1709
1710         /* build the slider */
1711         ADD_SLIDER( o_slider, mainFrame, [o_textfield_min frame].origin.x +
1712             [o_textfield_min frame].size.width + 6, -1, mainFrame.size.width -
1713             [o_textfield_max frame].size.width -
1714             [o_textfield_max frame].size.width - 14 -
1715             [o_textfield_min frame].origin.x, o_tooltip,
1716             p_item->min.i, p_item->max.i )
1717         [o_slider setIntValue: p_item->value.i];
1718         [o_slider setAutoresizingMask:NSViewWidthSizable ];
1719         [o_slider setTarget: self];
1720         [o_slider setAction: @selector(sliderChanged:)];
1721         [o_slider sendActionOn:NSLeftMouseUpMask | NSLeftMouseDownMask |
1722             NSLeftMouseDraggedMask];
1723         [self addSubview: o_slider];
1724
1725     }
1726     return self;
1727 }
1728
1729 - (void) alignWithXPosition:(int)i_xPos
1730 {
1731     NSRect frame;
1732     frame = [o_label frame];
1733     frame.origin.x = i_xPos - frame.size.width - 3;
1734     [o_label setFrame:frame];
1735
1736     frame = [o_textfield frame];
1737     frame.origin.x = i_xPos + 2;
1738     [o_textfield setFrame:frame];
1739 }
1740
1741 - (void)dealloc
1742 {
1743     [o_textfield release];
1744     [o_textfield_min release];
1745     [o_textfield_max release];
1746     [o_slider release];
1747     [super dealloc];
1748 }
1749
1750 - (IBAction)sliderChanged:(id)sender
1751 {
1752     [o_textfield setIntValue: [o_slider intValue]];
1753 }
1754
1755 - (void)textfieldChanged:(NSNotification *)o_notification
1756 {
1757     [o_slider setIntValue: [o_textfield intValue]];
1758 }
1759
1760 - (int)intValue
1761 {
1762     return [o_slider intValue];
1763 }
1764
1765 - (void)resetValues
1766 {
1767     int value = config_GetInt( VLCIntf, p_item->psz_name );
1768     [o_textfield setIntValue:value];
1769     [o_slider setIntValue:value];
1770     [super resetValues];
1771 }
1772 @end
1773
1774 @implementation FloatConfigControl
1775 - (id) initWithItem: (module_config_t *)_p_item
1776            withView: (NSView *)o_parent_view
1777 {
1778     NSRect mainFrame = [o_parent_view frame];
1779     NSString *o_labelString, *o_tooltip;
1780     mainFrame.size.height = 23;
1781     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1;
1782     mainFrame.origin.x = LEFTMARGIN;
1783     mainFrame.origin.y = 0;
1784
1785     if( [super initWithFrame: mainFrame item: _p_item] != nil )
1786     {
1787         i_view_type = CONFIG_ITEM_INTEGER;
1788
1789         o_tooltip = [[VLCMain sharedInstance] wrapString:
1790             [[VLCMain sharedInstance]
1791                 localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];
1792
1793         /* add the label */
1794         if( p_item->psz_text )
1795             o_labelString = [[VLCMain sharedInstance]
1796                                 localizedString: (char *)p_item->psz_text];
1797         else
1798             o_labelString = [NSString stringWithString:@""];
1799         ADD_LABEL( o_label, mainFrame, 0, -2, o_labelString, o_tooltip )
1800         [o_label setAutoresizingMask:NSViewNotSizable ];
1801         [self addSubview: o_label];
1802
1803         /* build the stepper */
1804         ADD_STEPPER( o_stepper, mainFrame, mainFrame.size.width - 19,
1805             0, o_tooltip, -100000, 100000)
1806         [o_stepper setFloatValue: p_item->value.f];
1807         [o_stepper setAutoresizingMask:NSViewMaxXMargin ];
1808         [self addSubview: o_stepper];
1809
1810         /* build the textfield */
1811         ADD_TEXTFIELD( o_textfield, mainFrame, mainFrame.size.width - 19 - 52,
1812             1, 49, o_tooltip, @"" )
1813         [o_textfield setFloatValue: p_item->value.f];
1814         [o_textfield setDelegate: self];
1815         [[NSNotificationCenter defaultCenter] addObserver: self
1816             selector: @selector(textfieldChanged:)
1817             name: NSControlTextDidChangeNotification
1818             object: o_textfield];
1819         [o_textfield setAutoresizingMask:NSViewMaxXMargin ];
1820         [self addSubview: o_textfield];
1821     }
1822     return self;
1823 }
1824
1825 - (void) alignWithXPosition:(int)i_xPos
1826 {
1827     NSRect frame;
1828     frame = [o_label frame];
1829     frame.origin.x = i_xPos - frame.size.width - 3;
1830     [o_label setFrame:frame];
1831
1832     frame = [o_textfield frame];
1833     frame.origin.x = i_xPos + 2;
1834     [o_textfield setFrame:frame];
1835
1836     frame = [o_stepper frame];
1837     frame.origin.x = i_xPos + [o_textfield frame].size.width + 5;
1838     [o_stepper setFrame:frame];
1839 }
1840
1841 - (void)dealloc
1842 {
1843     [o_stepper release];
1844     [o_textfield release];
1845     [super dealloc];
1846 }
1847
1848 - (IBAction)stepperChanged:(id)sender
1849 {
1850     [o_textfield setFloatValue: [o_stepper floatValue]];
1851 }
1852
1853 - (void)textfieldChanged:(NSNotification *)o_notification
1854 {
1855     [o_stepper setFloatValue: [o_textfield floatValue]];
1856 }
1857
1858 - (float)floatValue
1859 {
1860     return [o_stepper floatValue];
1861 }
1862
1863 - (void)resetValues
1864 {
1865     [o_textfield setFloatValue: config_GetFloat( VLCIntf, p_item->psz_name)];
1866     [super resetValues];
1867 }
1868 @end
1869
1870 @implementation RangedFloatConfigControl
1871 - (id) initWithItem: (module_config_t *)_p_item
1872            withView: (NSView *)o_parent_view
1873 {
1874     NSRect mainFrame = [o_parent_view frame];
1875     NSString *o_labelString, *o_tooltip;
1876     mainFrame.size.height = 50;
1877     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN;
1878     mainFrame.origin.x = LEFTMARGIN;
1879     mainFrame.origin.y = 0;
1880
1881     if( [super initWithFrame: mainFrame item: _p_item] != nil )
1882     {
1883         i_view_type = CONFIG_ITEM_RANGED_INTEGER;
1884
1885         o_tooltip = [[VLCMain sharedInstance] wrapString:
1886                      [[VLCMain sharedInstance]
1887                       localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];        
1888
1889         /* add the label */
1890         if( p_item->psz_text )
1891             o_labelString = [[VLCMain sharedInstance]
1892                                 localizedString: (char *)p_item->psz_text];
1893         else
1894             o_labelString = [NSString stringWithString:@""];
1895         ADD_LABEL( o_label, mainFrame, 0, -3, o_labelString, o_tooltip )
1896         [o_label setAutoresizingMask:NSViewNotSizable ];
1897         [self addSubview: o_label];
1898
1899         /* build the textfield */
1900         ADD_TEXTFIELD( o_textfield, mainFrame, [o_label frame].size.width + 2,
1901             28, 49, o_tooltip, @"" )
1902         [o_textfield setFloatValue: p_item->value.f];
1903         [o_textfield setAutoresizingMask:NSViewMaxXMargin ];
1904         [o_textfield setDelegate: self];
1905         [[NSNotificationCenter defaultCenter] addObserver: self
1906             selector: @selector(textfieldChanged:)
1907             name: NSControlTextDidChangeNotification
1908             object: o_textfield];
1909         [self addSubview: o_textfield];
1910
1911         /* build the mintextfield */
1912         ADD_LABEL( o_textfield_min, mainFrame, 12, -30, @"-8888", @"" )
1913         [o_textfield_min setFloatValue: p_item->min.f];
1914         [o_textfield_min setAutoresizingMask:NSViewMaxXMargin ];
1915         [o_textfield_min setAlignment:NSRightTextAlignment];
1916         [self addSubview: o_textfield_min];
1917
1918         /* build the maxtextfield */
1919         ADD_LABEL( o_textfield_max, mainFrame, mainFrame.size.width - 31,
1920             -30, @"8888", @"" )
1921         [o_textfield_max setFloatValue: p_item->max.f];
1922         [o_textfield_max setAutoresizingMask:NSViewMinXMargin ];
1923         [self addSubview: o_textfield_max];
1924
1925         /* build the slider */
1926         ADD_SLIDER( o_slider, mainFrame, [o_textfield_min frame].origin.x +
1927             [o_textfield_min frame].size.width + 6, -1, mainFrame.size.width -
1928             [o_textfield_max frame].size.width -
1929             [o_textfield_max frame].size.width - 14 -
1930             [o_textfield_min frame].origin.x, o_tooltip, p_item->min.f,
1931             p_item->max.f )
1932         [o_slider setFloatValue: p_item->value.f];
1933         [o_slider setAutoresizingMask:NSViewWidthSizable ];
1934         [o_slider setTarget: self];
1935         [o_slider setAction: @selector(sliderChanged:)];
1936         [o_slider sendActionOn:NSLeftMouseUpMask | NSLeftMouseDownMask |
1937             NSLeftMouseDraggedMask];
1938         [self addSubview: o_slider];
1939
1940     }
1941     return self;
1942 }
1943
1944 - (void) alignWithXPosition:(int)i_xPos
1945 {
1946     NSRect frame;
1947     frame = [o_label frame];
1948     frame.origin.x = i_xPos - frame.size.width - 3;
1949     [o_label setFrame:frame];
1950
1951     frame = [o_textfield frame];
1952     frame.origin.x = i_xPos + 2;
1953     [o_textfield setFrame:frame];
1954 }
1955
1956 - (void)dealloc
1957 {
1958     [o_textfield release];
1959     [o_textfield_min release];
1960     [o_textfield_max release];
1961     [o_slider release];
1962     [super dealloc];
1963 }
1964
1965 - (IBAction)sliderChanged:(id)sender
1966 {
1967     [o_textfield setFloatValue: [o_slider floatValue]];
1968 }
1969
1970 - (void)textfieldChanged:(NSNotification *)o_notification
1971 {
1972     [o_slider setFloatValue: [o_textfield floatValue]];
1973 }
1974
1975 - (float)floatValue
1976 {
1977     return [o_slider floatValue];
1978 }
1979
1980 - (void)resetValues
1981 {
1982     [o_textfield setFloatValue: config_GetFloat(VLCIntf, p_item->psz_name)];
1983     [o_slider setFloatValue: config_GetFloat(VLCIntf, p_item->psz_name)];
1984     [super resetValues];
1985 }
1986 @end
1987
1988 @implementation BoolConfigControl
1989
1990 - (id) initWithItem: (module_config_t *)_p_item
1991            withView: (NSView *)o_parent_view
1992 {
1993     NSRect mainFrame = [o_parent_view frame];
1994     NSString *o_labelString, *o_tooltip;
1995     mainFrame.size.height = 17;
1996     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN;
1997     mainFrame.origin.x = LEFTMARGIN;
1998     mainFrame.origin.y = 0;
1999
2000     if( [super initWithFrame: mainFrame item: _p_item] != nil )
2001     {
2002         i_view_type = CONFIG_ITEM_BOOL;
2003
2004         /* add the checkbox */
2005         o_tooltip = [[VLCMain sharedInstance]
2006             wrapString: [[VLCMain sharedInstance]
2007             localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];
2008         ADD_CHECKBOX( o_checkbox, mainFrame, 0,
2009                         0, @"", o_tooltip, p_item->value.i, NSImageLeft)
2010         [o_checkbox setAutoresizingMask:NSViewNotSizable ];
2011         [self addSubview: o_checkbox];
2012         /* add the label */
2013         if( p_item->psz_text )
2014             o_labelString = [[VLCMain sharedInstance]
2015                                 localizedString: (char *)p_item->psz_text];
2016         else
2017             o_labelString = [NSString stringWithString:@""];
2018         ADD_LABEL( o_label, mainFrame, [o_checkbox frame].size.width, 0, o_labelString, o_tooltip )
2019         [o_label setAutoresizingMask:NSViewNotSizable ];
2020         [self addSubview: o_label];
2021     }
2022     return self;
2023 }
2024
2025 - (void)dealloc
2026 {
2027     [o_checkbox release];
2028     [super dealloc];
2029 }
2030
2031 - (int)intValue
2032 {
2033     return [o_checkbox intValue];
2034 }
2035
2036 - (void)resetValues
2037 {
2038     [o_checkbox setState: config_GetInt( VLCIntf, p_item->psz_name)];
2039     [super resetValues];
2040 }
2041 @end
2042
2043 @implementation KeyConfigControl
2044 - (id) initWithItem: (module_config_t *)_p_item
2045            withView: (NSView *)o_parent_view
2046 {
2047     NSRect mainFrame = [o_parent_view frame];
2048     NSString *o_labelString, *o_tooltip;
2049     mainFrame.size.height = 22;
2050     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1;
2051     mainFrame.origin.x = LEFTMARGIN;
2052     mainFrame.origin.y = 0;
2053
2054     if( [super initWithFrame: mainFrame item: _p_item] != nil )
2055     {
2056         i_view_type = CONFIG_ITEM_KEY_AFTER_10_3;
2057
2058         o_tooltip = [[VLCMain sharedInstance] wrapString:
2059                      [[VLCMain sharedInstance]
2060                       localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];
2061
2062         /* add the label */
2063         if( p_item->psz_text )
2064             o_labelString = [[VLCMain sharedInstance]
2065                 localizedString: (char *)p_item->psz_text];
2066         else
2067             o_labelString = [NSString stringWithString:@""];
2068         ADD_LABEL( o_label, mainFrame, 0, -1, o_labelString, o_tooltip )
2069         [o_label setAutoresizingMask:NSViewNotSizable ];
2070         [self addSubview: o_label];
2071
2072         /* build the popup */
2073         ADD_POPUP( o_popup, mainFrame, [o_label frame].origin.x +
2074             [o_label frame].size.width + 3,
2075             -2, 0, o_tooltip )
2076         [o_popup setAutoresizingMask:NSViewWidthSizable ];
2077
2078         if( o_keys_menu == nil )
2079         {
2080             unsigned int i;
2081             o_keys_menu = [[NSMenu alloc] initWithTitle: @"Keys Menu"];
2082 #warning This does not work anymore. FIXME.
2083 #if 0
2084             for ( i = 0; i < sizeof(vlc_keys) / sizeof(key_descriptor_t); i++)
2085                 if( vlc_keys[i].psz_key_string )
2086                     POPULATE_A_KEY( o_keys_menu,
2087                         [NSString stringWithUTF8String:vlc_keys[i].psz_key_string]
2088                         , vlc_keys[i].i_key_code)
2089 #endif
2090         }
2091         [o_popup setMenu:[o_keys_menu copyWithZone:nil]];
2092         [o_popup selectItem:[[o_popup menu] itemWithTag:p_item->value.i]];
2093         [self addSubview: o_popup];
2094
2095     }
2096     return self;
2097 }
2098
2099 - (void) alignWithXPosition:(int)i_xPos
2100 {
2101     NSRect frame;
2102     NSRect superFrame = [self frame];
2103     frame = [o_label frame];
2104     frame.origin.x = i_xPos - frame.size.width - 3;
2105     [o_label setFrame:frame];
2106
2107     frame = [o_popup frame];
2108     frame.origin.x = i_xPos - 1;
2109     frame.size.width = superFrame.size.width - frame.origin.x + 2;
2110     [o_popup setFrame:frame];
2111 }
2112
2113 - (void)dealloc
2114 {
2115     [o_popup release];
2116     [super dealloc];
2117 }
2118
2119 - (int)intValue
2120 {
2121     return [o_popup selectedTag];
2122 }
2123
2124 - (void)resetValues
2125 {
2126     [o_popup selectItem:[[o_popup menu] itemWithTag:config_GetInt( VLCIntf, p_item->psz_name )]];
2127     [super resetValues];
2128 }
2129 @end
2130
2131 @implementation ModuleListConfigControl
2132 - (id) initWithItem: (module_config_t *)_p_item
2133            withView: (NSView *)o_parent_view
2134 {
2135     if( _p_item->i_type == CONFIG_ITEM_MODULE_LIST )
2136 //TODO....
2137         return nil;
2138
2139 //Fill our array to know how may items we have...
2140     module_t *p_parser, **p_list;
2141     size_t i_module_index;
2142     NSRect mainFrame = [o_parent_view frame];
2143     NSString *o_labelString, *o_textfieldString, *o_tooltip;
2144
2145     o_modulearray = [[NSMutableArray alloc] initWithCapacity:10];
2146     /* build a list of available modules */
2147     p_list = module_list_get( NULL );
2148     for( i_module_index = 0; p_list[i_module_index]; i_module_index++ )
2149     {
2150         int i;
2151         p_parser = p_list[i_module_index];
2152
2153         if( module_is_main( p_parser ) )
2154             continue;
2155
2156         unsigned int confsize;
2157         module_config_t *p_configlist = module_config_get( p_parser, &confsize );
2158
2159         for ( i = 0; i < confsize; i++ )
2160         {
2161             unsigned int unused;
2162             module_config_t *p_config = &p_configlist[i];
2163             NSString *o_modulelongname, *o_modulename;
2164             NSNumber *o_moduleenabled = nil;
2165
2166             /* Hack: required subcategory is stored in i_min */
2167             if( p_config->i_type == CONFIG_SUBCATEGORY &&
2168                 p_config->value.i == _p_item->min.i )
2169             {
2170                 o_modulelongname = [NSString stringWithUTF8String:
2171                                         module_GetLongName( p_parser )];
2172                 o_modulename = [NSString stringWithUTF8String:
2173                                         module_get_object( p_parser )];
2174
2175                 if( _p_item->value.psz &&
2176                     strstr( _p_item->value.psz, module_get_object( p_parser ) ) )
2177                     o_moduleenabled = [NSNumber numberWithBool:YES];
2178                 else
2179                     o_moduleenabled = [NSNumber numberWithBool:NO];
2180
2181                 [o_modulearray addObject:[NSMutableArray
2182                     arrayWithObjects: o_modulename, o_modulelongname,
2183                     o_moduleenabled, nil]];
2184             }
2185         }
2186         module_config_free( p_configlist );
2187     }
2188     module_list_free( p_list );
2189
2190     mainFrame.size.height = 30 + 18 * [o_modulearray count];
2191     mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN;
2192     mainFrame.origin.x = LEFTMARGIN;
2193     mainFrame.origin.y = 0;
2194     if( [super initWithFrame: mainFrame item: _p_item] != nil )
2195     {
2196         i_view_type = CONFIG_ITEM_MODULE_LIST;
2197
2198         o_tooltip = [[VLCMain sharedInstance] wrapString:
2199                      [[VLCMain sharedInstance]
2200                       localizedString: (char *)p_item->psz_longtext ] toWidth: PREFS_WRAP];
2201
2202         /* add the label */
2203         if( p_item->psz_text )
2204             o_labelString = [[VLCMain sharedInstance]
2205                                 localizedString: (char *)p_item->psz_text];
2206         else
2207             o_labelString = [NSString stringWithString:@""];
2208         ADD_LABEL( o_label, mainFrame, 0, -3, o_labelString, o_tooltip )
2209         [o_label setAutoresizingMask:NSViewNotSizable ];
2210         [self addSubview: o_label];
2211
2212         /* build the textfield */
2213         if( p_item->value.psz )
2214             o_textfieldString = [[VLCMain sharedInstance]
2215                 localizedString: (char *)p_item->value.psz];
2216         else
2217             o_textfieldString = [NSString stringWithString: @""];
2218         ADD_TEXTFIELD( o_textfield, mainFrame, [o_label frame].size.width + 2,
2219             mainFrame.size.height - 22, mainFrame.size.width -
2220             [o_label frame].size.width - 2, o_tooltip, o_textfieldString )
2221         [o_textfield setAutoresizingMask:NSViewWidthSizable ];
2222         [self addSubview: o_textfield];
2223
2224
2225 {
2226     NSRect s_rc = mainFrame;
2227     s_rc.size.height = mainFrame.size.height - 30;
2228     s_rc.size.width = mainFrame.size.width - 12;
2229     s_rc.origin.x = 12;
2230     s_rc.origin.y = 0;
2231     o_scrollview = [[[NSScrollView alloc] initWithFrame: s_rc] retain];
2232     [o_scrollview setDrawsBackground: NO];
2233     [o_scrollview setBorderType: NSBezelBorder];
2234     [o_scrollview setAutohidesScrollers:YES];
2235
2236     NSTableView *o_tableview;
2237     o_tableview = [[NSTableView alloc] initWithFrame : s_rc];
2238     [o_tableview setUsesAlternatingRowBackgroundColors:YES];
2239     [o_tableview setHeaderView:nil];
2240 /* TODO: find a good way to fix the row height and text size*/
2241 /* FIXME: support for multiple selection... */
2242 //    [o_tableview setAllowsMultipleSelection:YES];
2243
2244     NSCell *o_headerCell = [[NSCell alloc] initTextCell:@"Enabled"];
2245     NSCell *o_dataCell = [[NSButtonCell alloc] init];
2246     [(NSButtonCell*)o_dataCell setButtonType:NSSwitchButton];
2247     [o_dataCell setTitle:@""];
2248     [o_dataCell setFont:[NSFont systemFontOfSize:0]];
2249     NSTableColumn *o_tableColumn = [[NSTableColumn alloc]
2250         initWithIdentifier:@"Enabled"];
2251     [o_tableColumn setHeaderCell: o_headerCell];
2252     [o_tableColumn setDataCell: o_dataCell];
2253     [o_tableColumn setWidth:17];
2254     [o_tableview addTableColumn: o_tableColumn];
2255
2256     o_headerCell = [[NSCell alloc] initTextCell:@"Module Name"];
2257     o_dataCell = [[NSTextFieldCell alloc] init];
2258     [o_dataCell setFont:[NSFont systemFontOfSize:12]];
2259     o_tableColumn = [[NSTableColumn alloc]
2260         initWithIdentifier:@"Module"];
2261     [o_tableColumn setHeaderCell: o_headerCell];
2262     [o_tableColumn setDataCell: o_dataCell];
2263     [o_tableColumn setWidth:388 - 17];
2264     [o_tableview addTableColumn: o_tableColumn];
2265     [o_tableview registerForDraggedTypes:[NSArray arrayWithObjects:
2266             @"VLC media player module", nil]];
2267
2268     [o_tableview setDataSource:self];
2269     [o_tableview setTarget: self];
2270     [o_tableview setAction: @selector(tableChanged:)];
2271     [o_tableview sendActionOn:NSLeftMouseUpMask | NSLeftMouseDownMask |
2272         NSLeftMouseDraggedMask];
2273     [o_scrollview setDocumentView: o_tableview];
2274 }
2275     [o_scrollview setAutoresizingMask:NSViewWidthSizable ];
2276     [self addSubview: o_scrollview];
2277
2278
2279     }
2280     return self;
2281 }
2282
2283 - (void) alignWithXPosition:(int)i_xPos
2284 {
2285     ;
2286 }
2287
2288 - (IBAction)tableChanged:(id)sender
2289 {
2290     NSString *o_newstring = @"";
2291     unsigned int i;
2292     for( i = 0 ; i < [o_modulearray count] ; i++ )
2293         if( [[[o_modulearray objectAtIndex:i] objectAtIndex:2]
2294             boolValue] != NO )
2295         {
2296             o_newstring = [o_newstring stringByAppendingString:
2297                 [[o_modulearray objectAtIndex:i] objectAtIndex:0]];
2298             o_newstring = [o_newstring stringByAppendingString:@":"];
2299         }
2300
2301     [o_textfield setStringValue: [o_newstring
2302         substringToIndex: ([o_newstring length])?[o_newstring length] - 1:0]];
2303 }
2304
2305 - (void)dealloc
2306 {
2307     [o_scrollview release];
2308     [super dealloc];
2309 }
2310
2311
2312 - (char *)stringValue
2313 {
2314     return strdup( [[o_textfield stringValue] UTF8String] );
2315 }
2316
2317 -(void)resetValues
2318 {
2319 #warning Reset prefs of the module selector is broken atm. 
2320     NSLog( @"don't forget about modulelistconfig" );
2321     [super resetValues];
2322 }
2323
2324 @end
2325
2326 @implementation ModuleListConfigControl (NSTableDataSource)
2327
2328 - (BOOL)tableView:(NSTableView*)table writeRows:(NSArray*)rows
2329     toPasteboard:(NSPasteboard*)pb
2330 {
2331     // We only want to allow dragging of selected rows.
2332     NSEnumerator    *iter = [rows objectEnumerator];
2333     NSNumber        *row;
2334     while ((row = [iter nextObject]) != nil)
2335     {
2336         if (![table isRowSelected:[row intValue]])
2337             return NO;
2338     }
2339
2340     [pb declareTypes:[NSArray
2341         arrayWithObject:@"VLC media player module"] owner:nil];
2342     [pb setPropertyList:rows forType:@"VLC media player module"];
2343     return YES;
2344 }
2345
2346 - (NSDragOperation)tableView:(NSTableView*)table
2347     validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row
2348     proposedDropOperation:(NSTableViewDropOperation)op
2349 {
2350     // Make drops at the end of the table go to the end.
2351     if (row == -1)
2352     {
2353         row = [table numberOfRows];
2354         op = NSTableViewDropAbove;
2355         [table setDropRow:row dropOperation:op];
2356     }
2357
2358     // We don't ever want to drop onto a row, only between rows.
2359     if (op == NSTableViewDropOn)
2360         [table setDropRow:(row+1) dropOperation:NSTableViewDropAbove];
2361     return NSTableViewDropAbove;
2362 }
2363
2364 - (BOOL)tableView:(NSTableView*)table acceptDrop:(id <NSDraggingInfo>)info
2365     row:(NSInteger)dropRow dropOperation:(NSTableViewDropOperation)op;
2366 {
2367     NSPasteboard    *pb = [info draggingPasteboard];
2368     NSDragOperation srcMask = [info draggingSourceOperationMask];
2369     BOOL accepted = NO;
2370
2371     NS_DURING
2372
2373         NSArray *array;
2374
2375         // Intra-table drag - data is the array of rows.
2376         if (!accepted && (array =
2377             [pb propertyListForType:@"VLC media player module"]) != NULL)
2378         {
2379             NSEnumerator *iter = nil;
2380             id val;
2381             BOOL isCopy = (srcMask & NSDragOperationMove) ? NO:YES;
2382             // Move the modules
2383             iter = [array objectEnumerator];
2384             while ((val = [iter nextObject]) != NULL)
2385             {
2386                 NSArray *o_tmp = [[o_modulearray objectAtIndex:
2387                     [val intValue]] mutableCopyWithZone:nil];
2388                 [o_modulearray removeObject:o_tmp];
2389                 [o_modulearray insertObject:o_tmp
2390                     atIndex:(dropRow>[val intValue]) ? dropRow - 1 : dropRow];
2391                 dropRow++;
2392             }
2393
2394             // Select the newly-dragged items.
2395             iter = [array objectEnumerator];
2396 //TODO...
2397             [table deselectAll:self];
2398
2399             [self tableChanged:self];
2400             [table setNeedsDisplay:YES];
2401             // Indicate that we finished the drag.
2402             accepted = YES;
2403         }
2404         [table reloadData];
2405         [table setNeedsDisplay:YES];
2406
2407         NS_HANDLER
2408
2409             // An exception occurred. Uh-oh. Update the track table so that
2410             // it stays consistent, and re-raise the exception.
2411             [table reloadData];
2412             [localException raise];
2413             [table setNeedsDisplay:YES];
2414     NS_ENDHANDLER
2415
2416     return accepted;
2417 }
2418
2419 - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
2420 {
2421     return [o_modulearray count];
2422 }
2423
2424 - (id)tableView:(NSTableView *)aTableView
2425     objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
2426 {
2427     if( [[aTableColumn identifier] isEqualToString: @"Enabled"] )
2428         return [[o_modulearray objectAtIndex:rowIndex] objectAtIndex:2];
2429     if( [[aTableColumn identifier] isEqualToString: @"Module"] )
2430         return [[o_modulearray objectAtIndex:rowIndex] objectAtIndex:1];
2431
2432     return nil;
2433 }
2434
2435 - (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject
2436     forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
2437 {
2438     [[o_modulearray objectAtIndex:rowIndex] replaceObjectAtIndex:2
2439         withObject: anObject];
2440 }
2441 @end