]> git.sesse.net Git - vlc/blob - modules/gui/macosx/coredialogs.m
macosx: improve main menu handling for autogenerated items
[vlc] / modules / gui / macosx / coredialogs.m
1 /*****************************************************************************
2  * coredialogs.m: Mac OS X Core Dialogs
3  *****************************************************************************
4  * Copyright (C) 2005-2012 VLC authors and VideoLAN
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  * VLCCoreDialogProvider implementation
34  *****************************************************************************/
35 @implementation VLCCoreDialogProvider
36
37 static VLCCoreDialogProvider *_o_sharedInstance = nil;
38
39 + (VLCCoreDialogProvider *)sharedInstance
40 {
41     return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
42 }
43
44 -(id)init
45 {
46     if( _o_sharedInstance )
47         [self dealloc];
48     else
49     {
50         _o_sharedInstance = [super init];
51         o_error_panel = [[VLCErrorPanel alloc] init];
52         b_progress_cancelled = NO;
53     }
54
55     return _o_sharedInstance;
56 }
57
58 -(void)awakeFromNib
59 {
60     [o_auth_login_txt setStringValue: _NS("User name")];
61     [o_auth_pw_txt setStringValue: _NS("Password")];
62     [o_auth_cancel_btn setTitle: _NS("Cancel")];
63     [o_auth_ok_btn setTitle: _NS("OK")];
64     [o_prog_cancel_btn setTitle: _NS("Cancel")];
65     [o_prog_bar setUsesThreadedAnimation: YES];
66
67 }
68
69 -(void)performEventWithObject: (NSValue *)o_value ofType: (const char*)type
70 {
71     NSString *o_type = [NSString stringWithUTF8String:type];
72
73     if( [o_type isEqualToString: @"dialog-error"] )
74         [self performSelectorOnMainThread:@selector(showFatalDialog:) withObject:o_value waitUntilDone:YES];
75     else if( [o_type isEqualToString: @"dialog-critical"] )
76         [self performSelectorOnMainThread:@selector(showFatalWaitDialog:) withObject:o_value waitUntilDone:YES];
77     else if( [o_type isEqualToString: @"dialog-question"] )
78         [self performSelectorOnMainThread:@selector(showQuestionDialog:) withObject:o_value waitUntilDone:YES];
79     else if( [o_type isEqualToString: @"dialog-login"] )
80         [self performSelectorOnMainThread:@selector(showLoginDialog:) withObject:o_value waitUntilDone:YES];
81     else if( [o_type isEqualToString: @"dialog-progress-bar"] )
82         [self performSelectorOnMainThread:@selector(showProgressDialogOnMainThread:) withObject: o_value waitUntilDone:YES];
83     else
84         msg_Err( VLCIntf, "unhandled dialog type: '%s'", type );
85 }
86
87 -(void)showFatalDialog: (NSValue *)o_value
88 {
89     dialog_fatal_t *p_dialog = [o_value pointerValue];
90
91     [o_error_panel addError: [NSString stringWithUTF8String: p_dialog->title] withMsg: [NSString stringWithUTF8String: p_dialog->message]];
92     [o_error_panel showPanel];
93 }
94
95 -(void)showFatalWaitDialog: (NSValue *)o_value
96 {
97     dialog_fatal_t *p_dialog = [o_value pointerValue];
98     NSAlert *o_alert;
99
100     o_alert = [NSAlert alertWithMessageText: [NSString stringWithUTF8String: p_dialog->title] defaultButton: _NS("OK") alternateButton: nil otherButton: nil informativeTextWithFormat: @"%s", p_dialog->message];
101     [o_alert setAlertStyle: NSCriticalAlertStyle];
102     [o_alert runModal];
103 }
104
105 -(void)showQuestionDialog: (NSValue *)o_value
106 {
107     dialog_question_t *p_dialog = [o_value pointerValue];
108     NSAlert *o_alert;
109     NSString *o_yes, *o_no, *o_cancel;
110     NSInteger i_returnValue = 0;
111
112     if( p_dialog->yes != NULL )
113         o_yes = [NSString stringWithUTF8String: p_dialog->yes];
114     if( p_dialog->no != NULL )
115         o_no = [NSString stringWithUTF8String: p_dialog->no];
116     if( p_dialog->cancel != NULL )
117         o_cancel = [NSString stringWithUTF8String: p_dialog->cancel];
118
119     o_alert = [NSAlert alertWithMessageText: [NSString stringWithUTF8String: p_dialog->title] defaultButton: o_yes alternateButton:o_no otherButton: o_cancel informativeTextWithFormat: @"%s", p_dialog->message];
120     [o_alert setAlertStyle: NSInformationalAlertStyle];
121     i_returnValue = [o_alert runModal];
122
123     if( i_returnValue == NSAlertDefaultReturn )
124         p_dialog->answer = 1;
125     if( i_returnValue == NSAlertAlternateReturn )
126         p_dialog->answer = 2;
127     if( i_returnValue == NSAlertOtherReturn )
128         p_dialog->answer = 3;
129 }
130
131 -(void)showLoginDialog: (NSValue *)o_value
132 {
133     dialog_login_t *p_dialog = [o_value pointerValue];
134     NSInteger i_returnValue = 0;
135
136     [o_auth_title_txt setStringValue: [NSString stringWithUTF8String: p_dialog->title]];
137     [o_auth_win setTitle: [NSString stringWithUTF8String: p_dialog->title]];
138     [o_auth_description_txt setStringValue: [NSString stringWithUTF8String: p_dialog->message]];
139     [o_auth_login_fld setStringValue: @""];
140     [o_auth_pw_fld setStringValue: @""];
141
142     [o_auth_win center];
143     i_returnValue = [NSApp runModalForWindow: o_auth_win];
144     [o_auth_win close];
145     if( i_returnValue )
146     {
147         *p_dialog->username = strdup( [[o_auth_login_fld stringValue] UTF8String] );
148         *p_dialog->password = strdup( [[o_auth_pw_fld stringValue] UTF8String] );
149     }
150     else
151     {
152          *p_dialog->username = *p_dialog->password = NULL;
153     }
154 }
155
156 -(IBAction)loginDialogAction:(id)sender
157 {
158     if( [[sender title] isEqualToString: _NS("OK")] )
159         [NSApp stopModalWithCode: 1];
160     else
161         [NSApp stopModalWithCode: 0];
162 }
163
164 -(void)showProgressDialogOnMainThread: (NSValue *)o_value
165 {
166     /* we work-around a Cocoa limitation here, since you cannot delay an execution
167      * on the main thread within a single call */
168     b_progress_cancelled = NO;
169
170     dialog_progress_bar_t *p_dialog = [o_value pointerValue];
171
172     if (!p_dialog || b_progress_cancelled)
173         return;
174
175     if( p_dialog->title != NULL )
176     {
177         [o_prog_win setTitle: [NSString stringWithUTF8String: p_dialog->title]];
178         [o_prog_title_txt setStringValue: [NSString stringWithUTF8String: p_dialog->title]];
179     }
180     else
181     {
182         [o_prog_win setTitle: @""];
183         [o_prog_title_txt setStringValue: @""];
184     }
185     if( p_dialog->cancel != NULL )
186         [o_prog_cancel_btn setTitle: [NSString stringWithUTF8String: p_dialog->cancel]];
187     else
188         [o_prog_cancel_btn setTitle: _NS("Cancel")];
189     if( p_dialog->message != NULL )
190         [o_prog_description_txt setStringValue: [NSString stringWithUTF8String: p_dialog->message]];
191     else
192         [o_prog_description_txt setStringValue: @""];
193
194     if (VLCIntf)
195         [self performSelector:@selector(showProgressDialog:) withObject: o_value afterDelay:3.00];
196 }
197
198 -(void)showProgressDialog: (NSValue *)o_value
199 {
200     dialog_progress_bar_t *p_dialog = [o_value pointerValue];
201
202     if (!p_dialog || b_progress_cancelled)
203         return;
204
205     [o_prog_bar setDoubleValue: 0];
206     [o_prog_bar setIndeterminate: YES];
207     [o_prog_bar startAnimation: self];
208
209     [o_prog_win makeKeyAndOrderFront: self];
210 }
211
212 -(void)updateProgressPanelWithText: (NSString *)string andNumber: (double)d_number
213 {
214     [o_prog_description_txt setStringValue: string];
215     if (d_number > 0)
216         [o_prog_bar setIndeterminate: NO];
217     [o_prog_bar setDoubleValue: d_number];
218 }
219
220 -(void)destroyProgressPanel
221 {
222     b_progress_cancelled = YES;
223     [o_prog_bar stopAnimation: self];
224     [o_prog_win close];
225 }
226
227 -(IBAction)progDialogAction:(id)sender
228 {
229     b_progress_cancelled = YES;
230 }
231
232 -(BOOL)progressCancelled
233 {
234     return b_progress_cancelled;
235 }
236
237 -(id)errorPanel
238 {
239     return o_error_panel;
240 }
241
242 @end
243
244 /*****************************************************************************
245  * VLCErrorPanel implementation
246  *****************************************************************************/
247 @implementation VLCErrorPanel
248 -(id)init
249 {
250     [super init];
251
252     if( !b_nib_loaded )
253         b_nib_loaded = [NSBundle loadNibNamed:@"ErrorPanel" owner:self];
254
255     /* init data sources */
256     o_errors = [[NSMutableArray alloc] init];
257     o_icons = [[NSMutableArray alloc] init];
258
259     return self;
260 }
261
262 - (void)awakeFromNib
263 {
264     /* init strings */
265     [o_window setTitle: _NS("Errors and Warnings")];
266     [o_cleanup_button setTitle: _NS("Clean up")];
267     [o_messages_btn setTitle: _NS("Show Details")];
268 }
269
270 -(void)dealloc
271 {
272     [o_errors release];
273     [o_icons release];
274     [super dealloc];
275 }
276
277 -(void)showPanel
278 {
279     [o_window makeKeyAndOrderFront: self];
280 }
281
282 -(void)addError: (NSString *)o_error withMsg:(NSString *)o_msg
283 {
284     /* format our string as desired */
285     NSMutableAttributedString * ourError;
286     ourError = [[NSMutableAttributedString alloc] initWithString:
287         [NSString stringWithFormat:@"%@\n%@", o_error, o_msg]
288         attributes:
289         [NSDictionary dictionaryWithObject: [NSFont systemFontOfSize:11] forKey: NSFontAttributeName]];
290     [ourError
291         addAttribute: NSFontAttributeName
292         value: [NSFont boldSystemFontOfSize:11]
293         range: NSMakeRange( 0, [o_error length])];
294     [o_errors addObject: ourError];
295     [ourError release];
296
297     [o_icons addObject: [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kAlertStopIcon)]];
298
299     [o_error_table reloadData];
300 }
301
302 -(IBAction)cleanupTable:(id)sender
303 {
304     [o_errors removeAllObjects];
305     [o_icons removeAllObjects];
306     [o_error_table reloadData];
307 }
308
309 -(IBAction)showMessages:(id)sender
310 {
311     [[VLCMain sharedInstance] showMessagesPanel: sender];
312 }
313
314 /*----------------------------------------------------------------------------
315  * data source methods
316  *---------------------------------------------------------------------------*/
317 - (NSInteger)numberOfRowsInTableView:(NSTableView *)theDataTable
318 {
319     return [o_errors count];
320 }
321
322 - (id)tableView:(NSTableView *)theDataTable objectValueForTableColumn:
323     (NSTableColumn *)theTableColumn row: (NSInteger)row
324 {
325     if( [[theTableColumn identifier] isEqualToString: @"error_msg"] )
326         return [o_errors objectAtIndex: row];
327
328     if( [[theTableColumn identifier] isEqualToString: @"icon"] )
329         return [o_icons objectAtIndex: row];
330
331     return @"unknown identifier";
332 }
333
334 @end