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