]> git.sesse.net Git - vlc/blob - modules/gui/macosx/coredialogs.m
8ed476de35395288595251b9641f29cf0beffcce
[vlc] / modules / gui / macosx / coredialogs.m
1 /*****************************************************************************
2  * coredialogs.m: Mac OS X Core Dialogs
3  *****************************************************************************
4  * Copyright (C) 2005-2009 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Derk-Jan Hartman <hartman at videolan dot org>
8  *          Felix Paul Kühne <fkuehne at videolan dot org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #import "intf.h"
26 #import "coredialogs.h"
27 #import "misc.h"
28
29 /* for the icon in our custom error panel */
30 #import <ApplicationServices/ApplicationServices.h>
31
32
33 /*****************************************************************************
34  * Local prototypes.
35  *****************************************************************************/
36
37 bool b_progress_cancelled;
38 static void updateProgressPanel (void *, const char *, float);
39 static bool checkProgressPanel (void *);
40 static void destroyProgressPanel (void *);
41
42 /*****************************************************************************
43  * VLCCoreDialogProvider implementation
44  *****************************************************************************/
45 @implementation VLCCoreDialogProvider
46
47 static VLCCoreDialogProvider *_o_sharedInstance = nil;
48
49 + (VLCCoreDialogProvider *)sharedInstance
50 {
51     return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
52 }
53
54 -(id)init
55 {
56     if( _o_sharedInstance )
57         [self dealloc];
58     else
59     {
60         _o_sharedInstance = [super init];
61         [[NSNotificationCenter defaultCenter] addObserver:self
62                                                  selector:@selector(performDialogEvent:)
63                                                      name: @"VLCNewCoreDialogEventNotification"
64                                                    object:self];
65         [[NSNotificationCenter defaultCenter] addObserver: self
66                                                  selector:@selector(performProgressBarEvent:)
67                                                      name:@"VLCCoreDialogProgressBarUpdateNotification" 
68                                                    object: self];
69         [[NSNotificationCenter defaultCenter] addObserver: self
70                                                  selector:@selector(performProgressBarEvent:)
71                                                      name:@"VLCCoreDialogProgressBarDestroyNotification" 
72                                                    object: self];
73         o_error_panel = [[VLCErrorPanel alloc] init];
74         b_progress_cancelled = NO;
75     }
76     
77     return _o_sharedInstance;
78 }
79
80 -(void)awakeFromNib
81 {
82     [o_auth_login_txt setStringValue: _NS("User name")];
83     [o_auth_pw_txt setStringValue: _NS("Password")];
84     [o_auth_cancel_btn setTitle: _NS("Cancel")];
85     [o_auth_ok_btn setTitle: _NS("OK")];
86     [o_prog_cancel_btn setTitle: _NS("Cancel")];
87     [o_prog_bar setUsesThreadedAnimation: YES];
88
89 }    
90
91 -(void)performDialogEvent: (NSNotification *)o_notification
92 {
93     NSValue *o_value = [[o_notification userInfo] objectForKey:@"VLCDialogPointer"];
94     NSString *o_type = [[o_notification userInfo] objectForKey:@"VLCDialogType"];
95
96     if( [o_type isEqualToString: @"dialog-fatal"] )
97         [self showFatalDialog: o_value];
98     else if( [o_type isEqualToString: @"dialog-question"] )
99         [self showQuestionDialog: o_value];
100     else if( [o_type isEqualToString: @"dialog-login"] )
101         [self showLoginDialog: o_value];
102     else if( [o_type isEqualToString: @"dialog-progress-bar"] )
103         [self showProgressDialog: o_value];
104     else
105         msg_Err( VLCIntf, "unhandled dialog type: '%s'", [o_type UTF8String] );
106 }
107
108 -(void)showFatalDialog: (NSValue *)o_value
109 {
110     dialog_fatal_t *p_dialog = [o_value pointerValue];
111     /* do we need to block ? */
112     if( p_dialog->modal == YES )
113     {
114         NSAlert *o_alert;
115         o_alert = [NSAlert alertWithMessageText: [NSString stringWithUTF8String: p_dialog->title] defaultButton: _NS("OK") alternateButton: nil otherButton: nil informativeTextWithFormat: [NSString stringWithUTF8String: p_dialog->message]];
116         [o_alert setAlertStyle: NSCriticalAlertStyle];
117         [o_alert runModal];
118     }
119     else
120     {
121         [o_error_panel addError: [NSString stringWithUTF8String: p_dialog->title] withMsg: [NSString stringWithUTF8String: p_dialog->message]];
122         [o_error_panel showPanel];
123     }
124 }
125
126 -(void)showQuestionDialog: (NSValue *)o_value
127 {
128     dialog_question_t *p_dialog = [o_value pointerValue];
129     NSAlert *o_alert;
130     NSString *o_yes, *o_no, *o_cancel;
131     NSInteger i_returnValue = 0;
132     
133     if( p_dialog->yes != NULL )
134         o_yes = [NSString stringWithUTF8String: p_dialog->yes];
135     if( p_dialog->no != NULL )
136         o_no = [NSString stringWithUTF8String: p_dialog->no];
137     if( p_dialog->cancel != NULL )
138         o_cancel = [NSString stringWithUTF8String: p_dialog->cancel];
139
140     o_alert = [NSAlert alertWithMessageText: [NSString stringWithUTF8String: p_dialog->title] defaultButton: o_yes alternateButton:o_no otherButton: o_cancel informativeTextWithFormat: [NSString stringWithUTF8String: p_dialog->message]];
141     [o_alert setAlertStyle: NSInformationalAlertStyle];
142     i_returnValue = [o_alert runModal];
143
144     if( i_returnValue == NSAlertDefaultReturn )
145         p_dialog->answer = 1;
146     if( i_returnValue == NSAlertAlternateReturn )
147         p_dialog->answer = 2;
148     if( i_returnValue == NSAlertOtherReturn )
149         p_dialog->answer = 3;
150 }
151
152 -(void)showLoginDialog: (NSValue *)o_value
153 {
154     dialog_login_t *p_dialog = [o_value pointerValue];
155     NSInteger i_returnValue = 0;
156
157     [o_auth_title_txt setStringValue: [NSString stringWithUTF8String: p_dialog->title]];
158     [o_auth_win setTitle: [NSString stringWithUTF8String: p_dialog->title]];
159     [o_auth_description_txt setStringValue: [NSString stringWithUTF8String: p_dialog->message]];
160     [o_auth_login_fld setStringValue: @""];
161     [o_auth_pw_fld setStringValue: @""];
162
163     [o_auth_win center];
164     i_returnValue = [NSApp runModalForWindow: o_auth_win];
165     [o_auth_win close];
166     if( i_returnValue )
167     {
168         *p_dialog->username = strdup( [[o_auth_login_fld stringValue] UTF8String] );
169         *p_dialog->password = strdup( [[o_auth_pw_fld stringValue] UTF8String] );
170     }
171     else
172     {
173          *p_dialog->username = *p_dialog->password = NULL;
174     }
175 }
176
177 -(IBAction)loginDialogAction:(id)sender
178 {
179     if( [[sender title] isEqualToString: _NS("OK")] )
180         [NSApp stopModalWithCode: 1];
181     else
182         [NSApp stopModalWithCode: 0];
183 }
184
185 -(void)showProgressDialog: (NSValue *)o_value
186 {
187     dialog_progress_bar_t *p_dialog = [o_value pointerValue];
188
189     if( p_dialog->title != NULL )
190     {
191         [o_prog_win setTitle: [NSString stringWithUTF8String: p_dialog->title]];
192         [o_prog_title_txt setStringValue: [NSString stringWithUTF8String: p_dialog->title]];
193     }
194     else
195     {
196         [o_prog_win setTitle: @""];
197         [o_prog_title_txt setStringValue: @""];
198     }
199     if( p_dialog->cancel != NULL )
200         [o_prog_cancel_btn setTitle: [NSString stringWithUTF8String: p_dialog->cancel]];
201     else
202         [o_prog_cancel_btn setTitle: _NS("Cancel")];
203     if( p_dialog->message != NULL )
204         [o_prog_description_txt setStringValue: [NSString stringWithUTF8String: p_dialog->message]];
205     else
206         [o_prog_description_txt setStringValue: @""];
207     [o_prog_bar setDoubleValue: 0];
208
209     p_dialog->pf_update = updateProgressPanel;
210     p_dialog->pf_check = checkProgressPanel;
211     p_dialog->pf_destroy = destroyProgressPanel;
212     p_dialog->p_sys = self;
213
214     [NSApp runModalForWindow: o_prog_win];
215 }
216
217 -(void)performProgressBarEvent: (NSNotification *)o_notification
218 {
219     NSLog( @"%@ received", [o_notification name] );
220     if( [[o_notification name] isEqualToString: @"VLCCoreDialogProgressBarUpdateNotification"] )
221     {
222         NSNumber *o_number = [[o_notification userInfo] objectForKey:@"IntValue"];
223         NSString *o_text = [[o_notification userInfo] objectForKey:@"Text"];
224         [o_prog_description_txt setStringValue: o_text];
225         [o_prog_bar setDoubleValue: [o_number doubleValue]];
226     }
227     if( [[o_notification name] isEqualToString: @"VLCCoreDialogProgressBarDestroyNotification"] )
228     {
229         [NSApp stopModalWithCode: 0];
230         [o_prog_win close];
231     }
232 }
233
234 void updateProgressPanel (void *priv, const char *text, float value)
235 {
236     NSLog( @"we were updated with %s (%f)", text, value );
237     NSString *o_txt;
238     if( text != NULL )
239         o_txt = [NSString stringWithUTF8String: text];
240     [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCCoreDialogProgressBarUpdateNotification" object:[[VLCMain sharedInstance] getCoreDialogProvider] userInfo:[NSDictionary dictionaryWithObjectsAndKeys: o_txt, @"Text", [NSNumber numberWithInt: ((int)(value * 1000.))], @"IntValue", nil]];
241 }
242
243 void destroyProgressPanel (void *priv)
244 {
245     NSLog( @"we should destroy" );
246     [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCCoreDialogProgressBarDestroyNotification" object:[[VLCMain sharedInstance] getCoreDialogProvider] userInfo: nil];
247 }
248
249 bool checkProgressPanel (void *priv)
250 {
251     NSLog( @"we were checked" );
252     return b_progress_cancelled;
253 }
254
255 -(IBAction)progDialogAction:(id)sender
256 {
257     NSLog( @"buttonAction!" );
258     b_progress_cancelled = YES;
259 }
260
261 -(id)getErrorPanel
262 {
263     return o_error_panel;
264 }
265
266 -(void)dealloc
267 {
268     [[NSNotificationCenter defaultCenter] removeObserver:self];
269     [super dealloc];
270 }
271 @end
272
273 /*****************************************************************************
274  * VLCErrorPanel implementation
275  *****************************************************************************/
276 @implementation VLCErrorPanel
277 -(id)init
278 {
279     [super init];
280
281     nib_loaded = [NSBundle loadNibNamed:@"InteractionErrorPanel" owner:self];
282
283     /* init strings */
284     [o_window setTitle: _NS("Errors and Warnings")];
285     [o_cleanup_button setTitle: _NS("Clean up")];
286     [o_messages_btn setTitle: _NS("Show Details")];
287
288     /* init data sources */
289     o_errors = [[NSMutableArray alloc] init];
290     o_icons = [[NSMutableArray alloc] init];
291
292     return self;
293 }
294
295 -(void)dealloc
296 {
297     [o_errors release];
298     [o_icons release];
299     [super dealloc];
300 }
301
302 -(void)showPanel
303 {
304     [o_window makeKeyAndOrderFront: self];
305 }
306
307 -(void)addError: (NSString *)o_error withMsg:(NSString *)o_msg
308 {
309     /* format our string as desired */
310     NSMutableAttributedString * ourError;
311     ourError = [[NSMutableAttributedString alloc] initWithString:
312         [NSString stringWithFormat:@"%@\n%@", o_error, o_msg]
313         attributes:
314         [NSDictionary dictionaryWithObject: [NSFont systemFontOfSize:11] forKey: NSFontAttributeName]];
315     [ourError
316         addAttribute: NSFontAttributeName
317         value: [NSFont boldSystemFontOfSize:11]
318         range: NSMakeRange( 0, [o_error length])];
319     [o_errors addObject: ourError];
320     [ourError release];
321
322     [o_icons addObject: [NSImage imageWithErrorIcon]];
323
324     [o_error_table reloadData];
325 }
326
327 -(IBAction)cleanupTable:(id)sender
328 {
329     [o_errors removeAllObjects];
330     [o_icons removeAllObjects];
331     [o_error_table reloadData];
332 }
333
334 -(IBAction)showMessages:(id)sender
335 {
336     [[VLCMain sharedInstance] showMessagesPanel: sender];
337 }
338
339 /*----------------------------------------------------------------------------
340  * data source methods
341  *---------------------------------------------------------------------------*/
342 - (NSInteger)numberOfRowsInTableView:(NSTableView *)theDataTable
343 {
344     return [o_errors count];
345 }
346
347 - (id)tableView:(NSTableView *)theDataTable objectValueForTableColumn:
348     (NSTableColumn *)theTableColumn row: (NSInteger)row
349 {
350     if( [[theTableColumn identifier] isEqualToString: @"error_msg"] )
351         return [o_errors objectAtIndex: row];
352
353     if( [[theTableColumn identifier] isEqualToString: @"icon"] )
354         return [o_icons objectAtIndex: row];
355
356     return @"unknown identifier";
357 }
358
359 @end