]> git.sesse.net Git - vlc/blob - modules/gui/macosx/coredialogs.m
fd51456e8828ec4d3f771a5801b63cc7c9f0ad21
[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("Username")];
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 = [NSString stringWithUTF8String: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: toNSStr(p_dialog->title) withMsg: toNSStr(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: toNSStr(p_dialog->title) defaultButton: _NS("OK") alternateButton: nil otherButton: nil informativeTextWithFormat: @"%@", toNSStr(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     NSInteger i_returnValue = 0;
109   
110     o_alert = [NSAlert alertWithMessageText: toNSStr(p_dialog->title) defaultButton: toNSStr(p_dialog->yes) alternateButton: toNSStr(p_dialog->no) otherButton: toNSStr(p_dialog->cancel) informativeTextWithFormat:@"%@", toNSStr(p_dialog->message)];
111     [o_alert setAlertStyle: NSInformationalAlertStyle];
112     i_returnValue = [o_alert runModal];
113
114     if (i_returnValue == NSAlertDefaultReturn)
115         p_dialog->answer = 1;
116     if (i_returnValue == NSAlertAlternateReturn)
117         p_dialog->answer = 2;
118     if (i_returnValue == NSAlertOtherReturn)
119         p_dialog->answer = 3;
120 }
121
122 -(void)showLoginDialog: (NSValue *)o_value
123 {
124     dialog_login_t *p_dialog = [o_value pointerValue];
125     NSInteger i_returnValue = 0;
126
127     [o_auth_title_txt setStringValue: toNSStr(p_dialog->title)];
128     [o_auth_win setTitle: toNSStr(p_dialog->title)];
129     [o_auth_description_txt setStringValue: toNSStr(p_dialog->message)];
130     [o_auth_login_fld setStringValue: @""];
131     [o_auth_pw_fld setStringValue: @""];
132
133     [o_auth_win center];
134     i_returnValue = [NSApp runModalForWindow: o_auth_win];
135     [o_auth_win close];
136     if (i_returnValue)
137     {
138         *p_dialog->username = strdup([[o_auth_login_fld stringValue] UTF8String]);
139         *p_dialog->password = strdup([[o_auth_pw_fld stringValue] UTF8String]);
140     } else
141         *p_dialog->username = *p_dialog->password = NULL;
142 }
143
144 -(IBAction)loginDialogAction:(id)sender
145 {
146     if ([[sender title] isEqualToString: _NS("OK")])
147         [NSApp stopModalWithCode: 1];
148     else
149         [NSApp stopModalWithCode: 0];
150 }
151
152 -(void)showProgressDialogOnMainThread: (NSValue *)o_value
153 {
154     /* we work-around a Cocoa limitation here, since you cannot delay an execution
155      * on the main thread within a single call */
156     b_progress_cancelled = NO;
157
158     dialog_progress_bar_t *p_dialog = [o_value pointerValue];
159     if (!p_dialog || b_progress_cancelled)
160         return;
161
162     [o_prog_win setTitle: toNSStr(p_dialog->title)];
163     [o_prog_title_txt setStringValue: toNSStr(p_dialog->title)];
164
165     if (p_dialog->cancel != NULL)
166         [o_prog_cancel_btn setTitle: [NSString stringWithUTF8String:p_dialog->cancel]];
167     else
168         [o_prog_cancel_btn setTitle: _NS("Cancel")];
169
170     [o_prog_description_txt setStringValue: toNSStr(p_dialog->message)];
171
172     if (VLCIntf)
173         [self performSelector:@selector(showProgressDialog:) withObject: o_value afterDelay:3.00];
174 }
175
176 -(void)showProgressDialog: (NSValue *)o_value
177 {
178     dialog_progress_bar_t *p_dialog = [o_value pointerValue];
179
180     if (!p_dialog || b_progress_cancelled)
181         return;
182
183     [o_prog_bar setDoubleValue: 0];
184     [o_prog_bar setIndeterminate: YES];
185     [o_prog_bar startAnimation: self];
186
187     [o_prog_win makeKeyAndOrderFront: self];
188 }
189
190 -(void)updateProgressPanelWithText: (NSString *)string andNumber: (double)d_number
191 {
192     [o_prog_description_txt setStringValue: string];
193     if (d_number > 0)
194         [o_prog_bar setIndeterminate: NO];
195     [o_prog_bar setDoubleValue: d_number];
196 }
197
198 -(void)destroyProgressPanel
199 {
200     b_progress_cancelled = YES;
201     [o_prog_bar performSelectorOnMainThread:@selector(stopAnimation:) withObject:self waitUntilDone:YES];
202     [o_prog_win performSelectorOnMainThread:@selector(close) withObject:nil waitUntilDone:YES];
203 }
204
205 -(IBAction)progDialogAction:(id)sender
206 {
207     b_progress_cancelled = YES;
208 }
209
210 -(BOOL)progressCancelled
211 {
212     return b_progress_cancelled;
213 }
214
215 -(id)errorPanel
216 {
217     return o_error_panel;
218 }
219
220 @end
221
222 /*****************************************************************************
223  * VLCErrorPanel implementation
224  *****************************************************************************/
225 @implementation VLCErrorPanel
226 -(id)init
227 {
228     [super init];
229
230     if (!b_nib_loaded)
231         b_nib_loaded = [NSBundle loadNibNamed:@"ErrorPanel" owner:self];
232
233     /* init data sources */
234     o_errors = [[NSMutableArray alloc] init];
235     o_icons = [[NSMutableArray alloc] init];
236
237     return self;
238 }
239
240 - (void)awakeFromNib
241 {
242     /* init strings */
243     [o_window setTitle: _NS("Errors and Warnings")];
244     [o_cleanup_button setTitle: _NS("Clean up")];
245 }
246
247 -(void)dealloc
248 {
249     [o_errors release];
250     [o_icons release];
251     [super dealloc];
252 }
253
254 -(void)showPanel
255 {
256     [o_window makeKeyAndOrderFront: self];
257 }
258
259 -(void)addError: (NSString *)o_error withMsg:(NSString *)o_msg
260 {
261     /* format our string as desired */
262     NSMutableAttributedString * ourError;
263     ourError = [[NSMutableAttributedString alloc] initWithString:
264         [NSString stringWithFormat:@"%@\n%@", o_error, o_msg]
265         attributes:
266         [NSDictionary dictionaryWithObject: [NSFont systemFontOfSize:11] forKey: NSFontAttributeName]];
267     [ourError
268         addAttribute: NSFontAttributeName
269         value: [NSFont boldSystemFontOfSize:11]
270         range: NSMakeRange(0, [o_error length])];
271     [o_errors addObject: ourError];
272     [ourError release];
273
274     [o_icons addObject: [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kAlertStopIcon)]];
275
276     [o_error_table reloadData];
277 }
278
279 -(IBAction)cleanupTable:(id)sender
280 {
281     [o_errors removeAllObjects];
282     [o_icons removeAllObjects];
283     [o_error_table reloadData];
284 }
285
286 /*----------------------------------------------------------------------------
287  * data source methods
288  *---------------------------------------------------------------------------*/
289 - (NSInteger)numberOfRowsInTableView:(NSTableView *)theDataTable
290 {
291     return [o_errors count];
292 }
293
294 - (id)tableView:(NSTableView *)theDataTable objectValueForTableColumn:
295     (NSTableColumn *)theTableColumn row: (NSInteger)row
296 {
297     if ([[theTableColumn identifier] isEqualToString: @"error_msg"])
298         return [o_errors objectAtIndex:row];
299
300     if ([[theTableColumn identifier] isEqualToString: @"icon"])
301         return [o_icons objectAtIndex:row];
302
303     return @"unknown identifier";
304 }
305
306 @end