1 /*****************************************************************************
2 * coredialogs.m: Mac OS X Core Dialogs
3 *****************************************************************************
4 * Copyright (C) 2005-2012 VLC authors and VideoLAN
7 * Authors: Derk-Jan Hartman <hartman at videolan dot org>
8 * Felix Paul Kühne <fkuehne at videolan dot org>
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.
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.
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 *****************************************************************************/
26 #import "coredialogs.h"
29 /* for the icon in our custom error panel */
30 #import <ApplicationServices/ApplicationServices.h>
32 /*****************************************************************************
33 * VLCCoreDialogProvider implementation
34 *****************************************************************************/
35 @implementation VLCCoreDialogProvider
37 static VLCCoreDialogProvider *_o_sharedInstance = nil;
39 + (VLCCoreDialogProvider *)sharedInstance
41 return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
46 if (_o_sharedInstance)
49 _o_sharedInstance = [super init];
50 o_error_panel = [[VLCErrorPanel alloc] init];
51 b_progress_cancelled = NO;
54 return _o_sharedInstance;
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];
68 -(void)performEventWithObject: (NSValue *)o_value ofType: (const char*)type
70 NSString *o_type = @(type);
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];
83 msg_Err(VLCIntf, "unhandled dialog type: '%s'", type);
86 -(void)showFatalDialog: (NSValue *)o_value
88 dialog_fatal_t *p_dialog = [o_value pointerValue];
90 [o_error_panel addError: @(p_dialog->title) withMsg: @(p_dialog->message)];
91 [o_error_panel showPanel];
94 -(void)showFatalWaitDialog: (NSValue *)o_value
96 dialog_fatal_t *p_dialog = [o_value pointerValue];
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];
104 -(void)showQuestionDialog: (NSValue *)o_value
106 dialog_question_t *p_dialog = [o_value pointerValue];
108 NSString *o_yes, *o_no, *o_cancel;
109 NSInteger i_returnValue = 0;
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);
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];
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;
130 -(void)showLoginDialog: (NSValue *)o_value
132 dialog_login_t *p_dialog = [o_value pointerValue];
133 NSInteger i_returnValue = 0;
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: @""];
142 i_returnValue = [NSApp runModalForWindow: o_auth_win];
146 *p_dialog->username = strdup([[o_auth_login_fld stringValue] UTF8String]);
147 *p_dialog->password = strdup([[o_auth_pw_fld stringValue] UTF8String]);
149 *p_dialog->username = *p_dialog->password = NULL;
152 -(IBAction)loginDialogAction:(id)sender
154 if ([[sender title] isEqualToString: _NS("OK")])
155 [NSApp stopModalWithCode: 1];
157 [NSApp stopModalWithCode: 0];
160 -(void)showProgressDialogOnMainThread: (NSValue *)o_value
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;
166 dialog_progress_bar_t *p_dialog = [o_value pointerValue];
168 if (!p_dialog || b_progress_cancelled)
171 if (p_dialog->title != NULL)
173 [o_prog_win setTitle: @(p_dialog->title)];
174 [o_prog_title_txt setStringValue: @(p_dialog->title)];
176 [o_prog_win setTitle: @""];
177 [o_prog_title_txt setStringValue: @""];
179 if (p_dialog->cancel != NULL)
180 [o_prog_cancel_btn setTitle: @(p_dialog->cancel)];
182 [o_prog_cancel_btn setTitle: _NS("Cancel")];
183 if (p_dialog->message != NULL)
184 [o_prog_description_txt setStringValue: @(p_dialog->message)];
186 [o_prog_description_txt setStringValue: @""];
189 [self performSelector:@selector(showProgressDialog:) withObject: o_value afterDelay:3.00];
192 -(void)showProgressDialog: (NSValue *)o_value
194 dialog_progress_bar_t *p_dialog = [o_value pointerValue];
196 if (!p_dialog || b_progress_cancelled)
199 [o_prog_bar setDoubleValue: 0];
200 [o_prog_bar setIndeterminate: YES];
201 [o_prog_bar startAnimation: self];
203 [o_prog_win makeKeyAndOrderFront: self];
206 -(void)updateProgressPanelWithText: (NSString *)string andNumber: (double)d_number
208 [o_prog_description_txt setStringValue: string];
210 [o_prog_bar setIndeterminate: NO];
211 [o_prog_bar setDoubleValue: d_number];
214 -(void)destroyProgressPanel
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];
221 -(IBAction)progDialogAction:(id)sender
223 b_progress_cancelled = YES;
226 -(BOOL)progressCancelled
228 return b_progress_cancelled;
233 return o_error_panel;
238 /*****************************************************************************
239 * VLCErrorPanel implementation
240 *****************************************************************************/
241 @implementation VLCErrorPanel
247 b_nib_loaded = [NSBundle loadNibNamed:@"ErrorPanel" owner:self];
249 /* init data sources */
250 o_errors = [[NSMutableArray alloc] init];
251 o_icons = [[NSMutableArray alloc] init];
259 [o_window setTitle: _NS("Errors and Warnings")];
260 [o_cleanup_button setTitle: _NS("Clean up")];
261 [o_messages_btn setTitle: _NS("Show Details")];
273 [o_window makeKeyAndOrderFront: self];
276 -(void)addError: (NSString *)o_error withMsg:(NSString *)o_msg
278 /* format our string as desired */
279 NSMutableAttributedString * ourError;
280 ourError = [[NSMutableAttributedString alloc] initWithString:
281 [NSString stringWithFormat:@"%@\n%@", o_error, o_msg]
283 [NSDictionary dictionaryWithObject: [NSFont systemFontOfSize:11] forKey: NSFontAttributeName]];
285 addAttribute: NSFontAttributeName
286 value: [NSFont boldSystemFontOfSize:11]
287 range: NSMakeRange(0, [o_error length])];
288 [o_errors addObject: ourError];
291 [o_icons addObject: [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kAlertStopIcon)]];
293 [o_error_table reloadData];
296 -(IBAction)cleanupTable:(id)sender
298 [o_errors removeAllObjects];
299 [o_icons removeAllObjects];
300 [o_error_table reloadData];
303 -(IBAction)showMessages:(id)sender
305 [[VLCMain sharedInstance] showMessagesPanel: sender];
308 /*----------------------------------------------------------------------------
309 * data source methods
310 *---------------------------------------------------------------------------*/
311 - (NSInteger)numberOfRowsInTableView:(NSTableView *)theDataTable
313 return [o_errors count];
316 - (id)tableView:(NSTableView *)theDataTable objectValueForTableColumn:
317 (NSTableColumn *)theTableColumn row: (NSInteger)row
319 if ([[theTableColumn identifier] isEqualToString: @"error_msg"])
320 return o_errors[row];
322 if ([[theTableColumn identifier] isEqualToString: @"icon"])
325 return @"unknown identifier";