prefs.m 27.1 KB
Newer Older
1
2
3
/*****************************************************************************
 * prefs.m: MacOS X plugin for vlc
 *****************************************************************************
4
 * Copyright (C) 2002-2003 VideoLAN
hartman's avatar
hartman committed
5
 * $Id: prefs.m,v 1.23 2003/05/20 18:53:03 hartman Exp $
6
 *
hartman's avatar
hartman committed
7
8
 * Authors:	Jon Lech Johansen <jon-vl@nanocrew.net>
 *		Derk-Jan Hartman <thedj at users.sf.net>
9
10
11
12
13
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
14
 *
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#include <stdlib.h>                                      /* malloc(), free() */
#include <sys/param.h>                                    /* for MAXPATHLEN */
#include <string.h>

32
33
#include "intf.h"
#include "prefs.h"
34
35

/*****************************************************************************
36
 * VLCPrefs implementation
37
38
39
40
41
42
43
44
45
 *****************************************************************************/
@implementation VLCPrefs

- (id)init
{
    self = [super init];

    if( self != nil )
    {
hartman's avatar
hartman committed
46
        o_empty_view = [[NSView alloc] init];
47
48
49
50
51
52
53
    }

    return( self );
}

- (void)dealloc
{
hartman's avatar
hartman committed
54
55
56
    [o_empty_view release];
    [super dealloc];
}
57

hartman's avatar
hartman committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
- (void)awakeFromNib
{
    p_intf = [NSApp getIntf];
    b_advanced = config_GetInt( p_intf, "advanced" );

    [self initStrings];
    [o_advanced_ckb setState: b_advanced];
    [o_prefs_view setBorderType: NSGrooveBorder];
    [o_prefs_view setHasVerticalScroller: YES];
    [o_prefs_view setDrawsBackground: NO];
    [o_prefs_view setRulersVisible: YES];
    [o_prefs_view setDocumentView: o_empty_view];
    [o_tree selectRow:0 byExtendingSelection:NO];
    //[self loadConfigTree];
}
73

hartman's avatar
hartman committed
74
75
76
77
78
79
80
81
- (void)initStrings
{
    [o_prefs_window setTitle: _NS("Preferences")];
    [o_save_btn setTitle: _NS("Save")];
    [o_cancel_btn setTitle: _NS("Cancel")];
    [o_reset_btn setTitle: _NS("Reset All")];
    [o_advanced_ckb setTitle: _NS("Advanced")];
}
82

hartman's avatar
hartman committed
83
84
85
86
87
- (void)showPrefs
{
    [o_prefs_window center];
    [o_prefs_window makeKeyAndOrderFront:self];
}
88

hartman's avatar
hartman committed
89
90
91
92
93
- (IBAction)savePrefs: (id)sender
{
    config_SaveConfigFile( p_intf, NULL );
    [o_prefs_window orderOut:self];
}
94

hartman's avatar
hartman committed
95
96
97
- (IBAction)closePrefs: (id)sender
{
    [o_prefs_window orderOut:self];
98
99
}

hartman's avatar
hartman committed
100
- (IBAction)resetAll: (id)sender
101
{
hartman's avatar
hartman committed
102
103
    config_ResetAll( p_intf );
}
104

hartman's avatar
hartman committed
105
106
107
108
109
110
- (IBAction)advancedToggle: (id)sender
{
    b_advanced = !b_advanced;
    [o_advanced_ckb setState: b_advanced];
    [o_tree selectRow: [o_tree selectedRow] byExtendingSelection:NO];
}
111

hartman's avatar
hartman committed
112
113
114
115
- (void)loadConfigTree
{
    
}
116

hartman's avatar
hartman committed
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
- (void)outlineViewSelectionIsChanging:(NSNotification *)o_notification
{
}

- (void)outlineViewSelectionDidChange:(NSNotification *)o_notification
{
    [self showViewForID: [[o_tree itemAtRow:[o_tree selectedRow]] getObjectID] andName: [[o_tree itemAtRow:[o_tree selectedRow]] getName]];
}

- (void)configChanged:(id)o_unknown
{
    id o_vlc_config = [o_unknown isKindOfClass: [NSNotification class]] ?
                      [o_unknown object] : o_unknown;

    int i_type = [o_vlc_config configType];
    NSString *o_name = [o_vlc_config configName];
    char *psz_name = (char *)[o_name UTF8String];

    switch( i_type )
136
    {
gbazin's avatar
   
gbazin committed
137

hartman's avatar
hartman committed
138
    case CONFIG_ITEM_MODULE:
139
        {
hartman's avatar
hartman committed
140
141
142
143
144
145
146
            char *psz_value;
            NSString *o_value;

            o_value = [o_vlc_config titleOfSelectedItem];
            psz_value = (char *)[o_value UTF8String];

            config_PutPsz( p_intf, psz_name, psz_value );
147
        }
hartman's avatar
hartman committed
148
        break;
149

hartman's avatar
hartman committed
150
151
152
153
154
155
    case CONFIG_ITEM_STRING:
    case CONFIG_ITEM_FILE:
    case CONFIG_ITEM_DIRECTORY:
        {
            char *psz_value;
            NSString *o_value;
156

hartman's avatar
hartman committed
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
            o_value = [o_vlc_config stringValue];
            psz_value = (char *)[o_value UTF8String];

            config_PutPsz( p_intf, psz_name, psz_value );
        }
        break;

    case CONFIG_ITEM_INTEGER:
    case CONFIG_ITEM_BOOL:
        {
            int i_value = [o_vlc_config intValue];

            config_PutInt( p_intf, psz_name, i_value );
        }
        break;

    case CONFIG_ITEM_FLOAT:
        {
            float f_value = [o_vlc_config floatValue];

            config_PutFloat( p_intf, psz_name, f_value );
        }
        break;

    }
182
183
}

hartman's avatar
hartman committed
184
- (void)showViewForID: (int)i_id andName: (NSString *)o_item_name
185
{
186
    vlc_list_t *p_list;
hartman's avatar
hartman committed
187
    module_t *p_parser;
188
    module_config_t *p_item;
hartman's avatar
hartman committed
189
190
191
192
    
    int i_pos, i_module_tag, i_index;
    
    NSString *o_module_name;
193
194
195
196
    NSRect s_rc;                        /* rect                         */
    NSView *o_view;                     /* view                         */
    NSRect s_vrc;                       /* view rect                    */
    VLCTextField *o_text_field;         /* input field / label          */
hartman's avatar
hartman committed
197
    
198
    p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
199

hartman's avatar
hartman committed
200
201
202
    /* Get a pointer to the module */
    p_parser = (module_t *)vlc_object_get( p_intf, i_id );
    if( p_parser->i_object_type != VLC_OBJECT_MODULE )
203
    {
hartman's avatar
hartman committed
204
        /* 0OOoo something went really bad */
205
206
        return;
    }
hartman's avatar
hartman committed
207
    
208
    /* Enumerate config options and add corresponding config boxes */
hartman's avatar
hartman committed
209
    o_module_name = [NSString stringWithUTF8String: p_parser->psz_object_name];
gbazin's avatar
   
gbazin committed
210
    p_item = p_parser->p_config;
211
212
213
214
215
216

    i_pos = 0;
    o_view = nil;
    i_module_tag = 3;

#define X_ORIGIN 20
217
#define Y_ORIGIN (X_ORIGIN - 10)
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

#define CHECK_VIEW_HEIGHT \
    { \
        float f_new_pos = s_rc.origin.y + s_rc.size.height + X_ORIGIN; \
        if( f_new_pos > s_vrc.size.height ) \
        { \
            s_vrc.size.height = f_new_pos; \
            [o_view setFrame: s_vrc]; \
        } \
    }

#define CONTROL_LABEL( label ) \
    { \
        s_rc.origin.x += s_rc.size.width + 10; \
        s_rc.size.width = s_vrc.size.width - s_rc.origin.x - X_ORIGIN - 20; \
        o_text_field = [[NSTextField alloc] initWithFrame: s_rc]; \
        [o_text_field setDrawsBackground: NO]; \
        [o_text_field setBordered: NO]; \
        [o_text_field setEditable: NO]; \
        [o_text_field setSelectable: NO]; \
238
239
240
241
242
        if ( label ) \
        { \
            [o_text_field setStringValue: \
                [NSApp localizedString: label]]; \
        } \
243
        [o_text_field sizeToFit]; \
244
245
246
        [o_view addSubview: [o_text_field autorelease]]; \
    }

Christophe Massiot's avatar
Christophe Massiot committed
247
#define INPUT_FIELD( ctype, cname, label, w, msg, param, tip ) \
248
    { \
249
        char * psz_duptip = NULL; \
250
        if ( p_item->psz_longtext != NULL && [NSApp getEncoding] == NSISOLatin1StringEncoding ) \
251
            psz_duptip = strdup(p_item->psz_longtext); \
Christophe Massiot's avatar
Christophe Massiot committed
252
        s_rc.size.height = 25; \
253
254
255
256
257
258
259
        s_rc.size.width = w; \
        s_rc.origin.y += 10; \
        CHECK_VIEW_HEIGHT; \
        o_text_field = [[VLCTextField alloc] initWithFrame: s_rc]; \
        [o_text_field setAlignment: NSRightTextAlignment]; \
        CONTROL_CONFIG( o_text_field, o_module_name, ctype, cname ); \
        [o_text_field msg: param]; \
260
261
262
263
264
265
        if ( psz_duptip != NULL ) \
        { \
            [o_text_field setToolTip: [NSApp localizedString: \
                                       vlc_wraptext(psz_duptip, PREFS_WRAP)]]; \
            free(psz_duptip);\
        } \
266
267
268
269
270
271
272
273
274
275
        [o_view addSubview: [o_text_field autorelease]]; \
        [[NSNotificationCenter defaultCenter] addObserver: self \
            selector: @selector(configChanged:) \
            name: NSControlTextDidChangeNotification \
            object: o_text_field]; \
        CONTROL_LABEL( label ); \
        s_rc.origin.y += s_rc.size.height; \
        s_rc.origin.x = X_ORIGIN; \
    }

Christophe Massiot's avatar
Christophe Massiot committed
276
277
278
279
280
281
#define INPUT_FIELD_INTEGER( name, label, w, param, tip ) \
    INPUT_FIELD( CONFIG_ITEM_INTEGER, name, label, w, setIntValue, param, tip )
#define INPUT_FIELD_FLOAT( name, label, w, param, tip ) \
    INPUT_FIELD( CONFIG_ITEM_FLOAT, name, label, w, setFloatValue, param, tip )
#define INPUT_FIELD_STRING( name, label, w, param, tip ) \
    INPUT_FIELD( CONFIG_ITEM_STRING, name, label, w, setStringValue, param, tip )
282

hartman's avatar
hartman committed
283
284
285
286
287
288
289
    /* Init View */
    s_vrc = [[o_prefs_view contentView] bounds]; s_vrc.size.height -= 4;
    o_view = [[VLCFlippedView alloc] initWithFrame: s_vrc];
    s_rc.origin.x = X_ORIGIN;
    s_rc.origin.y = Y_ORIGIN;
    BOOL b_right_cat = FALSE;

290
291
    if( p_item ) do
    {
hartman's avatar
hartman committed
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
        if( p_item->i_type == CONFIG_HINT_CATEGORY )
        {
            if( !strcmp( p_parser->psz_object_name, "main" ) &&
                [o_item_name isEqualToString: [NSApp localizedString: p_item->psz_text]] )
            {
                b_right_cat = TRUE;
            } else if( strcmp( p_parser->psz_object_name, "main" ) )
            {
                 b_right_cat = TRUE;
            } else b_right_cat = FALSE; 
        } else if( p_item->i_type == CONFIG_HINT_END && !strcmp( p_parser->psz_object_name, "main" ) )
        {
            b_right_cat = FALSE;
        }
        
        if( (p_item->b_advanced && !b_advanced ) || !b_right_cat )
308
309
310
        {
            continue;
        }
311
312
        switch( p_item->i_type )
        {
hartman's avatar
hartman committed
313
            case CONFIG_ITEM_MODULE:
314
            {
hartman's avatar
hartman committed
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
                VLCPopUpButton *o_modules;
                module_t *p_a_module;
                char * psz_duptip = NULL;
                if ( p_item->psz_longtext != NULL && [NSApp getEncoding] == NSISOLatin1StringEncoding )
                    psz_duptip = strdup(p_item->psz_longtext);
        
                s_rc.size.height = 30;
                s_rc.size.width = 200;
                s_rc.origin.y += 10;
                
                CHECK_VIEW_HEIGHT;
    
                o_modules = [[VLCPopUpButton alloc] initWithFrame: s_rc];
                CONTROL_CONFIG( o_modules, o_module_name,
                                    CONFIG_ITEM_MODULE, p_item->psz_name );
                [o_modules setTarget: self];
                [o_modules setAction: @selector(configChanged:)];
                [o_modules sendActionOn:NSLeftMouseUpMask];
                if ( psz_duptip != NULL )
                {
                    [o_modules setToolTip: [NSApp localizedString:
                                            vlc_wraptext(psz_duptip, PREFS_WRAP)]];
                    free( psz_duptip );
                }
                [o_view addSubview: [o_modules autorelease]];
340

hartman's avatar
hartman committed
341
                [o_modules addItemWithTitle: _NS("Auto")];
342

hartman's avatar
hartman committed
343
                /* build a list of available modules */
344
                {
hartman's avatar
hartman committed
345
                    for( i_index = 0; i_index < p_list->i_count; i_index++ )
346
                    {
hartman's avatar
hartman committed
347
348
349
350
351
352
353
354
355
                        p_a_module = (module_t *)p_list->p_values[i_index].p_object ;
    
                        if( !strcmp( p_a_module->psz_capability,
                                    p_item->psz_type ) )
                        {
                            NSString *o_object_name = [NSString
                                stringWithCString: p_a_module->psz_object_name];
                            [o_modules addItemWithTitle: o_object_name];
                        }
356
357
                    }
                }
hartman's avatar
hartman committed
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    
                if( p_item->psz_value != NULL )
                {
                    NSString *o_value =
                        [NSString stringWithUTF8String: p_item->psz_value];
    
                    [o_modules selectItemWithTitle: o_value];
                }
                else
                {
                    [o_modules selectItemWithTitle: _NS("Auto")];
                }

                CONTROL_LABEL( p_item->psz_text );
                s_rc.origin.y += s_rc.size.height;
                s_rc.origin.x = X_ORIGIN;
374
            }
hartman's avatar
hartman committed
375
            break;
376

hartman's avatar
hartman committed
377
378
379
            case CONFIG_ITEM_STRING:
            case CONFIG_ITEM_FILE:
            case CONFIG_ITEM_DIRECTORY:
380
            {
hartman's avatar
hartman committed
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
    
                if( !p_item->ppsz_list )
                {
                    char *psz_value = p_item->psz_value ?
                                    p_item->psz_value : "";
    
                    INPUT_FIELD_STRING( p_item->psz_name, p_item->psz_text, 200,
                                        [NSString stringWithCString: psz_value],
                                        p_item->psz_longtext );
                }
                else
                {
                    int i;
                    VLCComboBox *o_combo_box;
                    char * psz_duptip = NULL;
                    if ( p_item->psz_longtext != NULL && [NSApp getEncoding] == NSISOLatin1StringEncoding )
                        psz_duptip = strdup(p_item->psz_longtext);
    
                    s_rc.size.height = 27;
                    s_rc.size.width = 200;
                    s_rc.origin.y += 10;
    
                    CHECK_VIEW_HEIGHT;
    
                    o_combo_box = [[VLCComboBox alloc] initWithFrame: s_rc];
                    CONTROL_CONFIG( o_combo_box, o_module_name,
                                    CONFIG_ITEM_STRING, p_item->psz_name );
                    [o_combo_box setTarget: self];
                    [o_combo_box setAction: @selector(configChanged:)];
                    [o_combo_box sendActionOn:NSLeftMouseUpMask];

                    if ( psz_duptip != NULL )
                    {
                        [o_combo_box setToolTip: [NSApp localizedString:
                                            vlc_wraptext(psz_duptip, PREFS_WRAP)]];
                        free( psz_duptip );
                    }
                    [o_view addSubview: [o_combo_box autorelease]];
                    
                    for( i=0; p_item->ppsz_list[i]; i++ )
                    {
                        [o_combo_box addItemWithObjectValue:
                            [NSString stringWithCString: p_item->ppsz_list[i]]];
                    }
                    [o_combo_box setStringValue: [NSString stringWithCString: 
                        p_item->psz_value ? p_item->psz_value : ""]];
    
                    CONTROL_LABEL( p_item->psz_text );
    
                    s_rc.origin.y += s_rc.size.height;
                    s_rc.origin.x = X_ORIGIN;
                }
    
434
            }
hartman's avatar
hartman committed
435
436
437
            break;
    
            case CONFIG_ITEM_INTEGER:
438
            {
hartman's avatar
hartman committed
439
440
                INPUT_FIELD_INTEGER( p_item->psz_name, p_item->psz_text, 70,
                                    p_item->i_value, p_item->psz_longtext );
441
            }
hartman's avatar
hartman committed
442
443
444
            break;
    
            case CONFIG_ITEM_FLOAT:
445
            {
hartman's avatar
hartman committed
446
447
                INPUT_FIELD_FLOAT( p_item->psz_name, p_item->psz_text, 70,
                                p_item->f_value, p_item->psz_longtext );
448
            }
hartman's avatar
hartman committed
449
450
451
            break;
    
            case CONFIG_ITEM_BOOL:
452
            {
hartman's avatar
hartman committed
453
                VLCButton *o_btn_bool;
454
                char * psz_duptip = NULL;
455
                if ( p_item->psz_longtext != NULL && [NSApp getEncoding] == NSISOLatin1StringEncoding )
456
                    psz_duptip = strdup(p_item->psz_longtext);
hartman's avatar
hartman committed
457
    
Christophe Massiot's avatar
Christophe Massiot committed
458
                s_rc.size.height = 27;
hartman's avatar
hartman committed
459
                s_rc.size.width = s_vrc.size.width - X_ORIGIN * 2 - 20;
460
                s_rc.origin.y += 10;
hartman's avatar
hartman committed
461
    
462
                CHECK_VIEW_HEIGHT;
hartman's avatar
hartman committed
463
464
465
466
467
468
    
                o_btn_bool = [[VLCButton alloc] initWithFrame: s_rc];
                [o_btn_bool setButtonType: NSSwitchButton];
                [o_btn_bool setIntValue: p_item->i_value];
                [o_btn_bool setTitle:
                    [NSApp localizedString: p_item->psz_text]];
469
470
                if ( psz_duptip != NULL )
                {
hartman's avatar
hartman committed
471
472
                    [o_btn_bool setToolTip: [NSApp localizedString:
                                            vlc_wraptext(psz_duptip, PREFS_WRAP)]];
473
474
                    free( psz_duptip );
                }
hartman's avatar
hartman committed
475
476
477
478
479
480
                [o_btn_bool setTarget: self];
                [o_btn_bool setAction: @selector(configChanged:)];
                CONTROL_CONFIG( o_btn_bool, o_module_name,
                                CONFIG_ITEM_BOOL, p_item->psz_name );
                [o_view addSubview: [o_btn_bool autorelease]];
    
481
482
                s_rc.origin.y += s_rc.size.height;
            }
hartman's avatar
hartman committed
483
484
            break;
    
485
            }
hartman's avatar
hartman committed
486
487
488
489
490
491
492
493
494
    
    #undef INPUT_FIELD_INTEGER
    #undef INPUT_FIELD_FLOAT
    #undef INPUT_FIELD_STRING
    #undef INPUT_FIELD
    #undef CHECK_VIEW_HEIGHT
    #undef CONTROL_LABEL
    #undef Y_ORIGIN
    #undef X_ORIGIN
495
        }
hartman's avatar
hartman committed
496
497
498
499
500
        while( p_item->i_type != CONFIG_HINT_END && p_item++ );
        vlc_list_release( p_list );
    
    [o_prefs_view setDocumentView: o_view];
    [o_prefs_view setNeedsDisplay: TRUE];
501
502
503
}


hartman's avatar
hartman committed
504
@end
505

hartman's avatar
hartman committed
506
@implementation VLCPrefs (NSTableDataSource)
507

hartman's avatar
hartman committed
508
509
- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    return (item == nil) ? [[VLCTreeItem rootItem] numberOfChildren] : [item numberOfChildren];
510
511
}

hartman's avatar
hartman committed
512
513
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    return (item == nil) ? YES : ([item numberOfChildren] != -1);
514
515
}

hartman's avatar
hartman committed
516
517
- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item {
    return (item == nil) ? [[VLCTreeItem rootItem] childAtIndex:index] : [item childAtIndex:index];
518
519
}

hartman's avatar
hartman committed
520
521
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    return (item == nil) ? @"" : (id)[item getName];
522
523
}

hartman's avatar
hartman committed
524
@end
525

hartman's avatar
hartman committed
526
@implementation VLCTreeItem
527

hartman's avatar
hartman committed
528
static VLCTreeItem *o_root_item = nil;
529

hartman's avatar
hartman committed
530
#define IsALeafNode ((id)-1)
531

hartman's avatar
hartman committed
532
- (id)initWithName: (NSString *)o_item_name ID: (int)i_id parent:(VLCTreeItem *)o_parent_item
533
{
hartman's avatar
hartman committed
534
    self = [super init];
535

hartman's avatar
hartman committed
536
    if( self != nil )
537
    {
hartman's avatar
hartman committed
538
539
540
        o_name = [o_item_name copy];
        i_object_id = i_id;
        o_parent = o_parent_item;
541
    }
hartman's avatar
hartman committed
542
    return( self );
543
544
}

hartman's avatar
hartman committed
545
546
547
548
+ (VLCTreeItem *)rootItem {
   if (o_root_item == nil) o_root_item = [[VLCTreeItem alloc] initWithName:@"main" ID: 0 parent:nil];
   return o_root_item;       
}
hartman's avatar
hartman committed
549

hartman's avatar
hartman committed
550
551
552
553
554
555
- (void)dealloc
{
    if (o_children != IsALeafNode) [o_children release];
    [o_name release];
    [super dealloc];
}
556

hartman's avatar
hartman committed
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
/* Creates and returns the array of children
 * Loads children incrementally */
- (NSArray *)children {
    if (o_children == NULL) {
        intf_thread_t *p_intf = [NSApp getIntf];
        vlc_list_t      *p_list;
        module_t        *p_module;
        module_config_t *p_item;
        int i_index,j;

        /* List the plugins */
        p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
        if( !p_list ) return nil;

        if( [[self getName] isEqualToString: @"main"] )
572
        {
hartman's avatar
hartman committed
573
574
575
576
            /*
            * Build a tree of the main options
            */
            for( i_index = 0; i_index < p_list->i_count; i_index++ )
577
            {
hartman's avatar
hartman committed
578
579
580
581
582
583
584
585
586
587
588
589
590
591
                p_module = (module_t *)p_list->p_values[i_index].p_object;
                if( !strcmp( p_module->psz_object_name, "main" ) )
                    break;
            }
            if( i_index < p_list->i_count )
            {
                /* We found the main module */
        
                /* Enumerate config categories and store a reference so we can
                 * generate their config panel them when it is asked by the user. */
                p_item = p_module->p_config;
                o_children = [[NSMutableArray alloc] initWithCapacity:10];

                if( p_item ) do
592
                {
hartman's avatar
hartman committed
593
594
595
596
597
598
599
600
601
602
                    NSString *o_child_name;
                    
                    switch( p_item->i_type )
                    {
                    case CONFIG_HINT_CATEGORY:
                        o_child_name = [NSString stringWithUTF8String: p_item->psz_text];
                        [o_children addObject:[[VLCTreeItem alloc] initWithName: o_child_name
                            ID: p_module->i_object_id parent:self]];
                        break;
                    }
603
                }
hartman's avatar
hartman committed
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
                while( p_item->i_type != CONFIG_HINT_END && p_item++ );
                
                /* Add the plugins item */
                [o_children addObject:[[VLCTreeItem alloc] initWithName: _NS("Modules")
                    ID: 0 parent:self]];
            }
            else
            {
                o_children = IsALeafNode;
            }
        }
        else if( [[self getName] isEqualToString: _NS("Modules")] )
        {
            /* Add the capabilities */
            o_children = [[NSMutableArray alloc] initWithCapacity:10];
            for( i_index = 0; i_index < p_list->i_count; i_index++ )
            {
                p_module = (module_t *)p_list->p_values[i_index].p_object;
        
                /* Exclude the main module */
                if( !strcmp( p_module->psz_object_name, "main" ) )
                    continue;
        
                /* Exclude empty plugins */
                p_item = p_module->p_config;
                if( !p_item ) continue;
                do
                {
                    if( p_item->i_type & CONFIG_ITEM )
                        break;
                }
                while( p_item->i_type != CONFIG_HINT_END && p_item++ );
                if( p_item->i_type == CONFIG_HINT_END ) continue;
        
                /* Create the capability tree if it doesn't already exist */
                NSString *o_capability;
                o_capability = [NSString stringWithUTF8String: p_module->psz_capability];
                if( !p_module->psz_capability || !*p_module->psz_capability )
642
                {
hartman's avatar
hartman committed
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
                    /* Empty capability ? Let's look at the submodules */
                    module_t * p_submodule;
                    for( j = 0; j < p_module->i_children; j++ )
                    {
                        p_submodule = (module_t*)p_module->pp_children[ j ];
                        if( p_submodule->psz_capability && *p_submodule->psz_capability )
                        {
                            o_capability = [NSString stringWithUTF8String: p_submodule->psz_capability];
                            BOOL b_found = FALSE;
                            for( j = 0; j < [o_children count]; j++ )
                            {
                                if( [[[o_children objectAtIndex:j] getName] isEqualToString: o_capability] )
                                {
                                    b_found = TRUE;
                                    break;
                                }
                            }
                            if( !b_found )
                            {
                                [o_children addObject:[[VLCTreeItem alloc] initWithName: o_capability
                                ID: 0 parent:self]];
                            }
                        }
                    }
                }
668

hartman's avatar
hartman committed
669
670
671
672
673
674
675
676
                BOOL b_found = FALSE;
                for( j = 0; j < [o_children count]; j++ )
                {
                    if( [[[o_children objectAtIndex:j] getName] isEqualToString: o_capability] )
                    {
                        b_found = TRUE;
                        break;
                    }
677
                }
hartman's avatar
hartman committed
678
                if( !b_found )
679
                {
hartman's avatar
hartman committed
680
681
                    [o_children addObject:[[VLCTreeItem alloc] initWithName: o_capability
                    ID: 0 parent:self]];
682
                }
683
684
            }
        }
hartman's avatar
hartman committed
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
        else if( [[o_parent getName] isEqualToString: _NS("Modules")] )
        {
            /* Now add the modules */
            o_children = [[NSMutableArray alloc] initWithCapacity:10];
            for( i_index = 0; i_index < p_list->i_count; i_index++ )
            {
                p_module = (module_t *)p_list->p_values[i_index].p_object;
        
                /* Exclude the main module */
                if( !strcmp( p_module->psz_object_name, "main" ) )
                    continue;
        
                /* Exclude empty plugins */
                p_item = p_module->p_config;
                if( !p_item ) continue;
                do
                {
                    if( p_item->i_type & CONFIG_ITEM )
                        break;
                }
                while( p_item->i_type != CONFIG_HINT_END && p_item++ );
                if( p_item->i_type == CONFIG_HINT_END ) continue;
        
                /* Check the capability */
                NSString *o_capability;
                o_capability = [NSString stringWithUTF8String: p_module->psz_capability];
                if( !p_module->psz_capability || !*p_module->psz_capability )
                {
                    /* Empty capability ? Let's look at the submodules */
                    module_t * p_submodule;
                    for( j = 0; j < p_module->i_children; j++ )
                    {
                        p_submodule = (module_t*)p_module->pp_children[ j ];
                        if( p_submodule->psz_capability && *p_submodule->psz_capability )
                        {
                            o_capability = [NSString stringWithUTF8String: p_submodule->psz_capability];
                            if( [o_capability isEqualToString: [self getName]] )
                            {
                            [o_children addObject:[[VLCTreeItem alloc] initWithName:
                                [NSString stringWithUTF8String: p_module->psz_object_name ]
                                ID: p_module->i_object_id parent:self]];
                            }
                        }
                    }
                }
                else if( [o_capability isEqualToString: [self getName]] )
                {
                    [o_children addObject:[[VLCTreeItem alloc] initWithName:
                        [NSString stringWithUTF8String: p_module->psz_object_name ]
                        ID: p_module->i_object_id parent:self]];
                }
            }
        }
        else
        {
            /* all the other stuff are leafs */
            o_children = IsALeafNode;
        }
743
    }
hartman's avatar
hartman committed
744
    return o_children;
745
746
}

hartman's avatar
hartman committed
747
- (int)getObjectID
748
{
hartman's avatar
hartman committed
749
750
    return i_object_id;
}
751

hartman's avatar
hartman committed
752
753
754
755
- (NSString *)getName
{
    return o_name;
}
756

hartman's avatar
hartman committed
757
758
- (VLCTreeItem *)childAtIndex:(int)i_index {
    return [[self children] objectAtIndex:i_index];
759
760
}

hartman's avatar
hartman committed
761
762
763
- (int)numberOfChildren {
    id i_tmp = [self children];
    return (i_tmp == IsALeafNode) ? (-1) : [i_tmp count];
764
765
}

hartman's avatar
hartman committed
766
- (BOOL)hasPrefs:(NSString *)o_module_name
767
{
hartman's avatar
hartman committed
768
769
770
771
772
    intf_thread_t *p_intf = [NSApp getIntf];
    module_t *p_parser;
    vlc_list_t *p_list;
    char *psz_module_name;
    int i_index;
773

hartman's avatar
hartman committed
774
775
776
777
778
779
    psz_module_name = (char *)[o_module_name lossyCString];

    /* look for module */
    p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );

    for( i_index = 0; i_index < p_list->i_count; i_index++ )
780
    {
hartman's avatar
hartman committed
781
782
783
784
785
786
787
788
        p_parser = (module_t *)p_list->p_values[i_index].p_object ;

        if( !strcmp( p_parser->psz_object_name, psz_module_name ) )
        {
            BOOL b_has_prefs = p_parser->i_config_items != 0;
            vlc_list_release( p_list );
            return( b_has_prefs );
        }
789
    }
790

hartman's avatar
hartman committed
791
    vlc_list_release( p_list );
792

hartman's avatar
hartman committed
793
    return( NO );
794
795
796
797
}

@end

hartman's avatar
hartman committed
798

799
800
801
802
803
804
805
806
807
808
@implementation VLCFlippedView

- (BOOL)isFlipped
{
    return( YES );
}

@end

IMPL_CONTROL_CONFIG(Button);
hartman's avatar
hartman committed
809
IMPL_CONTROL_CONFIG(PopUpButton);
810
811
IMPL_CONTROL_CONFIG(ComboBox);
IMPL_CONTROL_CONFIG(TextField);