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