]> git.sesse.net Git - vlc/blob - modules/gui/macosx/sfilters.m
FSF address change.
[vlc] / modules / gui / macosx / sfilters.m
1 /*****************************************************************************
2  * sfilter.m: MacOS X Subpicture filters dialogue
3  *****************************************************************************
4  * Copyright (C) 2005 the VideoLAN team
5  * $Id:$
6  *
7  * Authors: Felix K\9fhne <fkuehne@users.sf.net>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24
25 /*****************************************************************************
26  * Note: 
27  * the code used to bind with VLC's core is partially based upon the 
28  * RC-interface, written by Antoine Cellerier and Mark F. Moriarty  
29  * (members of the VideoLAN team) 
30  *****************************************************************************/
31
32 #import "sfilters.h"
33 #import "intf.h"
34 #import <vlc/vout.h>
35
36 /* TODO:
37     - check for memory leaks
38     - save the preferences, if requested
39     - fix stupid compilation warnings
40 */
41
42 @implementation VLCsFilters
43
44 static VLCsFilters *_o_sharedInstance = nil;
45
46 + (VLCsFilters *)sharedInstance
47 {
48     return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
49 }
50
51 - (id)init
52 {
53     if (_o_sharedInstance) {
54         [self dealloc];
55     } else {
56         _o_sharedInstance = [super init];
57     }
58
59     return _o_sharedInstance;
60 }
61
62 - (void)dealloc
63 {
64     [o_colors release];
65
66     [super dealloc];
67 }
68
69 - (void)initStrings
70 {
71     [o_sfilter_win setTitle: _NS("Subpicture Filters")];
72     [[o_sfilter_tabView tabViewItemAtIndex: 0] setLabel: _NS("Logo")];
73     [[o_sfilter_tabView tabViewItemAtIndex: 1] setLabel: _NS("Time")];
74     [[o_sfilter_tabView tabViewItemAtIndex: 2] setLabel: _NS("Marquee")];
75     [o_sfilter_saveSettings_ckb setTitle: _NS("Save settings")];
76     [o_logo_image_btn setTitle: _NS("Browse...")];
77     [o_logo_enabled_ckb setTitle: _NS("Enabled")];
78     [o_logo_image_lbl setStringValue: [_NS("Image") \
79         stringByAppendingString: @":"]];
80     [o_logo_pos_lbl setStringValue: [_NS("Position") \
81         stringByAppendingString: @":"]];
82     [o_logo_opaque_lbl setStringValue: [_NS("Opaqueness") \
83         stringByAppendingString: @":"]];
84     [o_time_enabled_ckb setTitle: _NS("Enabled")];
85     [o_time_stamp_lbl setStringValue: [_NS("Timestamp") \
86         stringByAppendingString: @":"]];
87     [o_time_size_lbl setStringValue: [_NS("Size") \
88         stringByAppendingString: @":"]];
89     [o_time_color_lbl setStringValue: [_NS("Color") \
90         stringByAppendingString: @":"]];
91     [o_time_opaque_lbl setStringValue: [_NS("Opaqueness") \
92         stringByAppendingString: @":"]];
93     [o_time_pos_lbl setStringValue: [_NS("Position") \
94         stringByAppendingString: @":"]];
95     [o_time_size_inPx_lbl setStringValue: _NS("(in pixels)")];
96     [o_marq_enabled_ckb setTitle: _NS("Enabled")];
97     [o_marq_color_lbl setStringValue: [_NS("Color") \
98         stringByAppendingString: @":"]];
99     [o_marq_marq_lbl setStringValue: [_NS("Marquee") \
100         stringByAppendingString: @":"]];
101     [o_marq_opaque_lbl setStringValue: [_NS("Opaqueness") \
102         stringByAppendingString: @":"]];
103     [o_marq_tmOut_lbl setStringValue: [_NS("Timeout") \
104         stringByAppendingString: @":"]];
105     [o_marq_tmOut_ms_lbl setStringValue: _NS("ms")];
106     [o_marq_pos_lbl setStringValue: [_NS("Position") \
107         stringByAppendingString: @":"]];
108     [o_marq_size_lbl setStringValue: [_NS("Size") \
109         stringByAppendingString: @":"]];
110     [o_time_color_lbl setStringValue: _NS("(in pixels)")];
111 }
112
113 - (void)awakeFromNib
114 {
115     /* colors as implemented at the beginning of marq.c and time.c
116      * feel free to add more colors, but remember to add them to these files 
117      * as well to keep a certain level of consistency across the interfaces */
118     NSArray * o_default;
119     NSArray * o_black;
120     NSArray * o_gray;
121     NSArray * o_silver;
122     NSArray * o_white;
123     NSArray * o_maroon;
124     NSArray * o_red;
125     NSArray * o_fuchsia;
126     NSArray * o_yellow;
127     NSArray * o_olive;
128     NSArray * o_green;
129     NSArray * o_teal;
130     NSArray * o_lime;
131     NSArray * o_purple;
132     NSArray * o_navy;
133     NSArray * o_blue;
134     NSArray * o_aqua;
135     o_default = [NSArray arrayWithObjects: _NS("Default"), @"-1", nil];
136     o_black = [NSArray arrayWithObjects: _NS("Black"), @"0x000000", nil];
137     o_gray = [NSArray arrayWithObjects: _NS("Gray"), @"0x808080", nil];
138     o_silver = [NSArray arrayWithObjects: _NS("Silver"), @"0xC0C0C0", nil];
139     o_white = [NSArray arrayWithObjects: _NS("White"), @"0xFFFFFF", nil];
140     o_maroon = [NSArray arrayWithObjects: _NS("Maroon"), @"0x800000", nil];
141     o_red = [NSArray arrayWithObjects: _NS("Red"), @"0xFF0000", nil];
142     o_fuchsia = [NSArray arrayWithObjects: _NS("Fuchsia"), @"0xFF00FF", nil];
143     o_yellow = [NSArray arrayWithObjects: _NS("Yellow"), @"0xFFFF00", nil];
144     o_olive = [NSArray arrayWithObjects: _NS("Olive"), @"0x808000", nil];
145     o_green = [NSArray arrayWithObjects: _NS("Green"), @"0x008000", nil];
146     o_teal = [NSArray arrayWithObjects: _NS("Teal"), @"0x008080", nil];
147     o_lime = [NSArray arrayWithObjects: _NS("Lime"), @"0x00FF00", nil];
148     o_purple = [NSArray arrayWithObjects: _NS("Purple"), @"0x800080", nil];
149     o_navy = [NSArray arrayWithObjects: _NS("Navy"), @"0x000080", nil];
150     o_blue = [NSArray arrayWithObjects: _NS("Blue"), @"0x0000FF", nil];
151     o_aqua = [NSArray arrayWithObjects: _NS("Aqua"), @"0x00FFFF", nil];
152     o_colors = [[NSArray alloc] initWithObjects: o_default, o_black, o_gray, \
153         o_silver, o_white, o_maroon, o_red, o_fuchsia, o_yellow, o_olive, \
154         o_green, o_teal, o_lime, o_purple, o_navy, o_blue, o_aqua, nil];
155
156     unsigned int x = 0;
157     [o_marq_color_pop removeAllItems];
158     [o_time_color_pop removeAllItems];
159     
160     /* we are adding tags to the items, so we can easily identify them even if 
161      * the menu was sorted */
162     while (x != [o_colors count])
163     {
164         [o_marq_color_pop addItemWithTitle: [[o_colors objectAtIndex:x] \
165             objectAtIndex:0]];
166         [[o_marq_color_pop lastItem] setTag: x];
167         
168         [o_time_color_pop addItemWithTitle: [[o_colors objectAtIndex:x] \
169             objectAtIndex:0]];
170         [[o_time_color_pop lastItem] setTag: x];
171         
172         x = (x + 1);
173     }
174
175     [o_marq_color_pop selectItemAtIndex:0];
176     [o_time_color_pop selectItemAtIndex:0];
177
178     /* define the relative positions and copy them to the menues
179      * we can destroy the array afterwards, because we are saving the ints 
180      * as tags to the menu-items */
181     NSArray * o_cnt_cnt;
182     NSArray * o_lft_cnt;
183     NSArray * o_rht_cnt;
184     NSArray * o_cnt_top;
185     NSArray * o_lft_top;
186     NSArray * o_rht_top;
187     NSArray * o_cnt_btm;
188     NSArray * o_lft_btm;
189     NSArray * o_rht_btm;
190     NSArray * o_positions;
191     o_cnt_cnt = [NSArray arrayWithObjects: _NS("Center-Center"), @"0", nil];
192     o_lft_cnt = [NSArray arrayWithObjects: _NS("Left-Center"), @"1", nil];
193     o_rht_cnt = [NSArray arrayWithObjects: _NS("Right-Center"), @"2", nil];
194     o_cnt_top = [NSArray arrayWithObjects: _NS("Center-Top"), @"4", nil];
195     o_lft_top = [NSArray arrayWithObjects: _NS("Left-Top"), @"5", nil];
196     o_rht_top = [NSArray arrayWithObjects: _NS("Right-Top"), @"6", nil];
197     o_cnt_btm = [NSArray arrayWithObjects: _NS("Center-Bottom"), @"8", nil];
198     o_lft_btm = [NSArray arrayWithObjects: _NS("Left-Bottom"), @"9", nil];
199     o_rht_btm = [NSArray arrayWithObjects: _NS("Right-Bottom"), @"10", nil];
200     o_positions = [[NSArray alloc] initWithObjects: o_cnt_cnt, o_lft_cnt, \
201         o_rht_cnt, o_cnt_top, o_lft_top, o_rht_top, o_cnt_btm, o_lft_btm, \
202         o_rht_btm, nil];
203         
204     x = 0;
205     [o_time_pos_rel_pop removeAllItems];
206     [o_marq_pos_rel_pop removeAllItems];
207     [o_logo_pos_rel_pop removeAllItems];
208     
209     /* we are adding a tag here, so we can easily select an item later on */
210     while ( x != [o_positions count] )
211     {
212         [o_time_pos_rel_pop addItemWithTitle: [[o_positions objectAtIndex:x] \
213             objectAtIndex:0]];
214         [[o_time_pos_rel_pop lastItem] setTag: [[[o_positions objectAtIndex:x] \
215             objectAtIndex:1] intValue]];
216         [o_marq_pos_rel_pop addItemWithTitle: [[o_positions objectAtIndex:x] \
217             objectAtIndex:0]];
218         [[o_marq_pos_rel_pop lastItem] setTag: [[[o_positions objectAtIndex:x] \
219             objectAtIndex:1] intValue]];
220         [o_logo_pos_rel_pop addItemWithTitle: [[o_positions objectAtIndex:x] \
221             objectAtIndex:0]];
222         [[o_logo_pos_rel_pop lastItem] setTag: [[[o_positions objectAtIndex:x] \
223             objectAtIndex:1] intValue]];
224
225         x = (x + 1);
226     }
227     [o_positions release];
228
229     NSArray * o_sizes;
230     o_sizes = [[NSArray alloc] initWithObjects: @"6", @"8", @"10", @"11", @"12",\
231         @"14", @"13", @"16", @"18", @"24", @"36", @"48", @"64", @"72", @"96", \
232         @"144", @"288", nil];
233     [o_marq_size_pop removeAllItems];
234     [o_marq_size_pop addItemsWithTitles: o_sizes];
235     [o_time_size_pop removeAllItems];
236     [o_time_size_pop addItemsWithTitles: o_sizes];
237     [o_sizes release];
238 }
239
240 - (void)showAsPanel
241 {
242     /* called from intf.m */
243     [o_sfilter_win displayIfNeeded];
244     [o_sfilter_win makeKeyAndOrderFront:nil];
245
246     intf_thread_t * p_intf = VLCIntf;
247
248     /* retrieve the marquee settings */
249     int x = 0;
250     int tempInt = config_GetInt( p_intf, "marq-color" );
251     while( strtol([[[o_colors objectAtIndex:x] objectAtIndex:1] UTF8String], \
252         NULL, 0) != tempInt )
253     {
254         x = (x + 1);
255         
256         if( x >= [o_marq_color_pop numberOfItems] )
257         {
258             x = 0;
259             return;
260         }
261     }
262     [o_marq_color_pop selectItemAtIndex: x];
263     [o_marq_marq_fld setStringValue: [NSString stringWithUTF8String: \
264         config_GetPsz( p_intf, "marq-marquee" )]];
265     [o_marq_opaque_sld setIntValue: config_GetInt( p_intf, "marq-opacity")];
266     x = 0;
267     tempInt = config_GetInt( p_intf, "marq-position" );
268     while( tempInt != [[o_marq_pos_rel_pop itemAtIndex:x] tag] )
269     {
270         x = (x + 1);
271         
272         if( x >= [o_marq_pos_rel_pop numberOfItems] )
273         {
274             x = 0;
275             return;
276         }
277     }
278     [o_marq_pos_rel_pop selectItemAtIndex:x];
279     x = 0;
280     tempInt = config_GetInt( p_intf, "marq-size" );
281     while( [[[o_marq_size_pop itemAtIndex: x] title] intValue] != tempInt )
282         x = (x + 1);
283         
284         if( x >= [o_marq_size_pop numberOfItems] )
285         {
286             x = 0;
287             return;
288         }
289     [o_marq_size_pop selectItemAtIndex: x];
290     [o_marq_tmOut_fld setStringValue: [[NSNumber numberWithInt: \
291         config_GetInt( p_intf, "marq-timeout" )] stringValue]];
292     
293     /* retrieve the time settings */
294     x = 0;
295     tempInt = config_GetInt( p_intf, "time-color" );
296     while( strtol([[[o_colors objectAtIndex:x] objectAtIndex:1] UTF8String], \
297         NULL, 0) != tempInt )
298     {
299         x = (x + 1);
300         
301         if( x >= [o_time_color_pop numberOfItems] )
302         {
303             x = 0;
304             return;
305         }
306     }
307     [o_time_color_pop selectItemAtIndex: x];
308     [o_time_stamp_fld setStringValue: [NSString stringWithUTF8String: \
309         config_GetPsz( p_intf, "time-format" )]];
310     [o_time_opaque_sld setIntValue: config_GetInt( p_intf, "time-opacity")];
311     x = 0;
312     tempInt = config_GetInt( p_intf, "time-size" );
313     while( [[[o_time_size_pop itemAtIndex: x] title] intValue] != tempInt )
314         x = (x + 1);
315         
316         if( x >= [o_time_size_pop numberOfItems] )
317         {
318             x = 0;
319             return;
320         }
321     [o_time_size_pop selectItemAtIndex: x];
322     x = 0;
323     tempInt = config_GetInt( p_intf, "time-position" );
324     while( tempInt != [[o_time_pos_rel_pop itemAtIndex:x] tag] )
325     {
326         x = (x + 1);
327         
328         if( x >= [o_time_pos_rel_pop numberOfItems] )
329         {
330             x = 0;
331             return;
332         }
333     }
334     
335     /* retrieve the logo settings */
336     [o_logo_opaque_sld setIntValue: config_GetInt( p_intf, "logo-transparency")];
337     /* in case that no path has been saved yet */
338     NSString * tempString = [[NSString alloc] initWithUTF8String: \
339         config_GetPsz( p_intf, "logo-file" )];
340     if( [tempString length] == 0 )
341     {
342         [o_logo_image_fld setStringValue: @""];
343     }
344     else
345     {
346         [o_logo_image_fld setStringValue: tempString ];
347     }
348     [tempString release];
349     x = 0;
350     tempInt = config_GetInt( p_intf, "logo-position" );
351     while( tempInt != [[o_logo_pos_rel_pop itemAtIndex:x] tag] )
352     {
353         x = (x + 1);
354         
355         if( x >= [o_logo_pos_rel_pop numberOfItems] )
356         {
357             x = 0;
358             return;
359         }
360     }
361     
362     /* enable the wanted filters */
363     char * psz_subfilters;
364     psz_subfilters = config_GetPsz( p_intf, "sub-filter" );
365     if( psz_subfilters )
366     {
367         [o_marq_enabled_ckb setState: (int)strstr( psz_subfilters, "marq")];
368         [o_logo_enabled_ckb setState: (int)strstr( psz_subfilters, "logo")];
369         [o_time_enabled_ckb setState: (int)strstr( psz_subfilters, "time")];
370         [self enableMarq];
371         [self enableLogo];
372         [self enableTime];
373     }
374 }
375
376 - (IBAction)logo_selectFile:(id)sender
377 {
378     NSOpenPanel * openPanel = [NSOpenPanel openPanel];
379     SEL sel = @selector(logo_getFile:returnCode:contextInfo:);
380     [openPanel beginSheetForDirectory:nil file:nil types: [NSArray \
381         arrayWithObjects: @"png", @"PNG", @"'PNGf'", nil] modalForWindow: \
382         o_sfilter_win modalDelegate:self didEndSelector:sel contextInfo:nil];
383 }
384
385 - (void)logo_getFile: (NSOpenPanel *)sheet returnCode: \
386     (int)returnCode contextInfo: (void *)contextInfo
387 {
388     if (returnCode == NSOKButton)
389     {
390         [o_logo_image_fld setStringValue: [sheet filename]];
391     }
392 }
393
394 - (IBAction)propertyChanged:(id)sender
395 {
396     intf_thread_t * p_intf = VLCIntf;
397     input_thread_t * p_input = (input_thread_t *)vlc_object_find( p_intf, \
398         VLC_OBJECT_INPUT, FIND_ANYWHERE );
399
400     vlc_value_t val;
401
402     /* general properties */
403     if( sender == o_sfilter_saveSettings_ckb)
404     {
405         o_save_settings = [o_sfilter_saveSettings_ckb state]; 
406     }
407
408     /* marquee */
409     else if( sender == o_marq_marq_fld )
410     {
411         if( [[o_marq_marq_fld stringValue] length] == 0 )
412         {
413             val.psz_string = "";
414         }
415         else
416         {
417             val.psz_string = [[o_marq_marq_fld stringValue] UTF8String];
418         }
419
420         if( p_input )
421             var_Set( p_input->p_libvlc, "marq-marquee", val );
422
423         config_PutPsz( p_intf, "marq-marquee", val.psz_string );
424     }
425     
426     else if( sender == o_marq_pos_rel_pop )
427     {
428         val.i_int = [[o_marq_pos_rel_pop selectedItem] tag];
429
430         if( p_input )
431             var_Set( p_input->p_libvlc, "marq-position", val );
432
433         config_PutInt( p_intf, "marq-position", val.i_int );
434     }
435     
436     else if( sender == o_marq_color_pop )
437     {
438         val.i_int = strtol( [[[o_colors objectAtIndex: [o_marq_color_pop \
439             indexOfSelectedItem]] objectAtIndex: 1] UTF8String], NULL, 0 );
440
441         if( p_input )
442             var_Set( p_input->p_libvlc, "marq-color", val );
443
444         config_PutInt( p_intf, "marq-color", val.i_int );
445     }
446     
447     else if( sender == o_marq_opaque_sld )
448     {
449         val.i_int = [o_marq_opaque_sld intValue];
450
451         if( p_input )
452             var_Set( p_input->p_libvlc, "marq-opacity", val );
453
454         config_PutInt( p_intf, "marq-opacity", val.i_int );
455     }
456     
457     else if( sender == o_marq_size_pop )
458     {
459         val.i_int = [[o_marq_size_pop titleOfSelectedItem] intValue];
460
461         if( p_input )
462             var_Set( p_input->p_libvlc, "marq-size", val );
463
464         config_PutInt( p_intf, "marq-size", val.i_int );
465     }
466     
467     else if( sender == o_marq_tmOut_fld && [[sender stringValue] length] > 0 )
468     {
469         val.i_int = [o_marq_tmOut_fld intValue];
470
471         if( p_input )
472             var_Set( p_input->p_libvlc, "marq-timeout", val );
473
474         config_PutInt( p_intf, "marq-timeout", val.i_int );
475     }
476     
477     /* time */
478     
479     else if( sender == o_time_stamp_fld )
480     {
481         if( [[o_time_stamp_fld stringValue] length] == 0 )
482         {
483             val.psz_string = "";
484         }
485         else
486         {
487             val.psz_string = [[o_time_stamp_fld stringValue] UTF8String];
488         }
489
490         if( p_input )
491             var_Set( p_input->p_libvlc, "time-format", val );
492
493         config_PutPsz( p_intf, "time-format", val.psz_string );
494     }
495
496     else if( sender == o_time_pos_rel_pop )
497     {
498         val.i_int = [[o_time_pos_rel_pop selectedItem] tag];
499
500         if( p_input )
501             var_Set( p_input->p_libvlc, "time-position", val );
502
503         config_PutInt( p_intf, "time-position", val.i_int );
504     }
505     
506     else if( sender == o_time_color_pop )
507     {
508         val.i_int = strtol( [[[o_colors objectAtIndex: [o_time_color_pop \
509             indexOfSelectedItem]] objectAtIndex: 1] UTF8String], NULL, 0 );
510
511         if( p_input )
512             var_Set( p_input->p_libvlc, "time-color", val );
513
514         config_PutInt( p_intf, "time-color", val.i_int );
515     }
516     
517     else if( sender == o_time_opaque_sld )
518     {
519         val.i_int = [o_time_opaque_sld intValue];
520
521         if( p_input )
522             var_Set( p_input->p_libvlc, "time-opacity", val );
523
524         config_PutInt( p_intf, "time-opacity", val.i_int );
525     }
526     
527     else if( sender == o_time_size_pop )
528     {
529         val.i_int = [[o_time_size_pop titleOfSelectedItem] intValue];
530
531         if( p_input )
532             var_Set( p_input->p_libvlc, "time-size", val );
533
534         config_PutInt( p_intf, "time-size", val.i_int );
535     }
536
537     /* logo */
538     else if( sender == o_logo_opaque_sld )
539     {
540         val.i_int = [o_logo_opaque_sld intValue];
541
542         if( p_input )
543             var_Set( p_input->p_libvlc, "logo-transparency", val );
544
545         config_PutInt( p_intf, "logo-transparency", val.i_int );
546     }
547     
548     else if( sender == o_logo_pos_rel_pop )
549     {
550         val.i_int = [[o_logo_pos_rel_pop selectedItem] tag];
551
552         if( p_input )
553             var_Set( p_input->p_libvlc, "logo-position", val );
554
555         config_PutInt( p_intf, "logo-position", val.i_int );
556     }
557
558     /* clean up */
559     if ( p_input )
560     {
561         o_config_changed = YES;
562         vlc_object_release( p_input );
563     }
564 }
565
566 - (IBAction)enableFilter:(id)sender
567 {
568     if( sender == o_marq_enabled_ckb )
569     {
570         if( [o_marq_enabled_ckb state] == NSOnState )
571         {
572             [self changeFiltersString:"marq" onOrOff:VLC_TRUE];
573         }
574         else
575         {
576             [self changeFiltersString:"marq" onOrOff:VLC_FALSE];
577         }
578         [self enableMarq];
579     }
580     if( sender == o_logo_enabled_ckb )
581     {
582         if( [o_logo_enabled_ckb state] == NSOnState )
583         {
584             [self changeFiltersString:"logo" onOrOff:VLC_TRUE];
585         }
586         else
587         {
588             [self changeFiltersString:"logo" onOrOff:VLC_FALSE];
589         }
590         [self enableLogo];
591     }
592     if( sender == o_time_enabled_ckb )
593     {
594         if( [o_time_enabled_ckb state] == NSOnState )
595         {
596             [self changeFiltersString:"time" onOrOff:VLC_TRUE];
597         }
598         else
599         {
600             [self changeFiltersString:"time" onOrOff:VLC_FALSE];
601         }
602         [self enableTime];
603     }    
604 }
605
606 - (void)enableMarq
607 {
608     [o_marq_color_pop setEnabled: [o_marq_enabled_ckb state]];
609     [o_marq_marq_fld setEnabled: [o_marq_enabled_ckb state]];
610     [o_marq_opaque_sld setEnabled: [o_marq_enabled_ckb state]];
611     [o_marq_size_pop setEnabled: [o_marq_enabled_ckb state]];
612     [o_marq_tmOut_fld setEnabled: [o_marq_enabled_ckb state]];
613     [o_marq_pos_rel_pop setEnabled: [o_marq_enabled_ckb state]];
614 }
615
616 - (void)enableTime
617 {
618     [o_time_color_pop setEnabled: [o_time_enabled_ckb state]];
619     [o_time_stamp_fld setEnabled: [o_time_enabled_ckb state]];
620     [o_time_opaque_sld setEnabled: [o_time_enabled_ckb state]];
621     [o_time_size_pop setEnabled: [o_time_enabled_ckb state]];
622     [o_time_pos_rel_pop setEnabled: [o_time_enabled_ckb state]];
623 }
624
625 - (void)enableLogo
626 {
627     [o_logo_image_btn setEnabled: [o_logo_enabled_ckb state]];
628     [o_logo_image_fld setEnabled: [o_logo_enabled_ckb state]];
629     [o_logo_opaque_sld setEnabled: [o_logo_enabled_ckb state]];
630     [o_logo_pos_rel_pop setEnabled: [o_logo_enabled_ckb state]];
631 }
632
633 - (void)changeFiltersString:(char *)psz_name onOrOff:(vlc_bool_t )b_add
634 {
635     /* copied from ../wxwidgets/extrapanel.cpp
636      * renamed to conform with Cocoa's rules
637      * and slightly modified to suit our needs */
638
639     intf_thread_t * p_intf = VLCIntf;
640     
641     char *psz_parser, *psz_string;
642     psz_string = config_GetPsz( p_intf, "sub-filter" );
643     
644     if( !psz_string ) psz_string = strdup("");
645
646     psz_parser = strstr( psz_string, psz_name );
647
648     if( b_add )
649     {
650         if( !psz_parser )
651         {
652             psz_parser = psz_string;
653             asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
654                             psz_string, psz_name );
655             free( psz_parser );
656         }
657         else
658         {
659             return;
660         }
661     }
662     else
663     {
664         if( psz_parser )
665         {
666             memmove( psz_parser, psz_parser + strlen(psz_name) +
667                             (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
668                             strlen(psz_parser + strlen(psz_name)) + 1 );
669
670             /* Remove trailing : : */
671             if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
672             {
673                 *(psz_string+strlen(psz_string ) -1 ) = '\0';
674             }
675          }
676          else
677          {
678              free( psz_string );
679              return;
680          }
681     }
682     
683     config_PutPsz( p_intf, "sub-filter", psz_string );
684     
685     /* Try to set on the fly */
686     /* FIXME: enable this once we support on-the-fly addition of this kind of
687      * filters...
688     vout_thread_t *p_vout;
689     p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
690                                               FIND_ANYWHERE );
691     if( p_vout )
692     {
693         var_SetString( p_vout, "sub-filter", psz_string );
694         vlc_object_release( p_vout );
695     }*/
696
697     free( psz_string );
698
699     vlc_object_release( p_intf );
700
701     o_config_changed = YES;
702 }
703 @end