X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2Finteraction.m;h=c62e36c4fcb93f38ac78b9ac9b0faac0074d3854;hb=8a5d95d032dd1d3773858ece1d5efe2f970d6bab;hp=ce694b4dcfe2a1bec35f432f046487994d2c8c9c;hpb=e90c868f4cba1ec0b18c5be5d230e32f1aa99c8a;p=vlc diff --git a/modules/gui/macosx/interaction.m b/modules/gui/macosx/interaction.m index ce694b4dcf..c62e36c4fc 100644 --- a/modules/gui/macosx/interaction.m +++ b/modules/gui/macosx/interaction.m @@ -1,7 +1,7 @@ /***************************************************************************** * interaction.h: Mac OS X interaction dialogs ***************************************************************************** - * Copyright (C) 2005-2006 the VideoLAN team + * Copyright (C) 2005-2007 the VideoLAN team * $Id$ * * Authors: Derk-Jan Hartman @@ -11,7 +11,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -22,8 +22,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ -#include "intf.h" +#import "intf.h" #import "interaction.h" +#import "misc.h" + +/* for the icons in our custom error panel */ +#import /***************************************************************************** * VLCInteractionList implementation @@ -39,6 +43,8 @@ name: @"VLCNewInteractionEventNotification" object:self]; + o_error_panel = [[VLCErrorInteractionPanel alloc] init]; + return self; } @@ -72,9 +78,8 @@ -(void)addInteraction: (interaction_dialog_t *)p_dialog { - VLCInteraction *o_interaction = [[VLCInteraction alloc] initDialog: p_dialog]; - + p_dialog->p_private = (void *)o_interaction; [o_interaction_list addObject:[o_interaction autorelease]]; [o_interaction runDialog]; @@ -85,6 +90,11 @@ [o_interaction_list removeObject:o_interaction]; } +-(id)getErrorPanel +{ + return o_error_panel; +} + -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; @@ -92,7 +102,6 @@ [o_interaction_list release]; [super dealloc]; } - @end /***************************************************************************** @@ -110,7 +119,6 @@ -(void)runDialog { - int i = 0; id o_window = NULL; if( !p_dialog ) msg_Err( p_intf, "no available interaction framework" ); @@ -120,11 +128,21 @@ nib_interact_loaded = [NSBundle loadNibNamed:@"Interaction" owner:self]; [o_prog_cancel_btn setTitle: _NS("Cancel")]; [o_prog_bar setUsesThreadedAnimation: YES]; + [o_auth_login_txt setStringValue: _NS("Login:")]; + [o_auth_pw_txt setStringValue: _NS("Password:")]; + [o_auth_cancel_btn setTitle: _NS("Cancel")]; + [o_auth_ok_btn setTitle: _NS("OK")]; + [o_input_ok_btn setTitle: _NS("OK")]; + [o_input_cancel_btn setTitle: _NS("Cancel")]; + o_mainIntfPgbar = [[VLCMain sharedInstance] getMainIntfPgbar]; } - NSString *o_title = [NSString stringWithUTF8String:p_dialog->psz_title ? p_dialog->psz_title : "title"]; + NSString *o_title = [NSString stringWithUTF8String:p_dialog->psz_title ? p_dialog->psz_title : _("Error")]; NSString *o_description = [NSString stringWithUTF8String:p_dialog->psz_description ? p_dialog->psz_description : ""]; - + NSString *o_defaultButton = p_dialog->psz_default_button ? [NSString stringWithUTF8String:p_dialog->psz_default_button] : nil; + NSString *o_alternateButton = p_dialog->psz_alternate_button ? [NSString stringWithUTF8String:p_dialog->psz_alternate_button] : nil; + NSString *o_otherButton = p_dialog->psz_other_button ? [NSString stringWithUTF8String:p_dialog->psz_other_button] : nil; + vout_thread_t *p_vout = vlc_object_find( VLCIntf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); if( p_vout != NULL ) { @@ -132,7 +150,7 @@ while( ( o_window = [o_enum nextObject] ) ) { - if( [[o_window className] isEqualToString: @"VLCWindow"] ) + if( [[o_window className] isEqualToString: @"VLCVoutWindow"] ) { vlc_object_release( (vlc_object_t *)p_vout ); break; @@ -144,66 +162,97 @@ { o_window = [NSApp mainWindow]; } - + +#if 0 msg_Dbg( p_intf, "Title: %s", [o_title UTF8String] ); msg_Dbg( p_intf, "Description: %s", [o_description UTF8String] ); - if( p_dialog->i_id == DIALOG_ERRORS ) + msg_Dbg( p_intf, "Delivered flag: %i", p_dialog->i_flags ); +#endif + + if( p_dialog->i_flags & DIALOG_BLOCKING_ERROR ) { - for( i = 0; i < p_dialog->i_widgets; i++ ) - { - msg_Err( p_intf, "Error: %s", p_dialog->pp_widgets[i]->psz_text ); - } + msg_Dbg( p_intf, "error panel requested" ); + NSBeginInformationalAlertSheet( o_title, _NS("OK"), nil, nil, + o_window, self, @selector(sheetDidEnd: returnCode: contextInfo:), + NULL, nil, o_description ); } - else + else if( p_dialog->i_flags & DIALOG_NONBLOCKING_ERROR ) { - for( i = 0; i < p_dialog->i_widgets; i++ ) - { - msg_Dbg( p_intf, "widget: %s", p_dialog->pp_widgets[i]->psz_text ); - o_description = [o_description stringByAppendingString: \ - [NSString stringWithUTF8String: \ - p_dialog->pp_widgets[i]->psz_text]]; - } - if( p_dialog->i_flags & DIALOG_OK_CANCEL ) - { - msg_Dbg( p_intf, "requested flag: DIALOG_OK_CANCEL" ); - NSBeginInformationalAlertSheet( o_title, @"OK" , @"Cancel", nil, \ - o_window, self,@selector(sheetDidEnd: returnCode: contextInfo:),\ - NULL, nil, o_description ); - } - else if( p_dialog->i_flags & DIALOG_YES_NO_CANCEL ) - { - msg_Dbg( p_intf, "requested flag: DIALOG_YES_NO_CANCEL" ); - NSBeginInformationalAlertSheet( o_title, @"Yes", @"No", @"Cancel", \ - o_window, self,@selector(sheetDidEnd: returnCode: contextInfo:),\ - NULL, nil, o_description ); - } - else if( p_dialog->i_type & WIDGET_PROGRESS ) - { - msg_Dbg( p_intf, "requested type: WIDGET_PROGRESS" ); - [o_prog_title setStringValue: o_title]; - [o_prog_description setStringValue: o_description]; - [o_prog_bar setDoubleValue: 0]; - [NSApp beginSheet: o_prog_win modalForWindow: o_window \ - modalDelegate: self didEndSelector: nil contextInfo: nil]; - [o_prog_win makeKeyWindow]; - } + msg_Dbg( p_intf, "addition to non-blocking error panel received" ); + [[[[VLCMain sharedInstance] getInteractionList] getErrorPanel] + addError: o_title withMsg: o_description]; + } + else if( p_dialog->i_flags & DIALOG_WARNING ) + { + msg_Dbg( p_intf, "addition to non-blocking warning panel received" ); + [[[[VLCMain sharedInstance] getInteractionList] getErrorPanel] + addWarning: o_title withMsg: o_description]; + } + else if( p_dialog->i_flags & DIALOG_YES_NO_CANCEL ) + { + msg_Dbg( p_intf, "yes-no-cancel-dialog requested" ); + NSBeginInformationalAlertSheet( o_title, o_defaultButton, + o_alternateButton, o_otherButton, o_window, self, + @selector(sheetDidEnd: returnCode: contextInfo:), NULL, nil, + o_description ); + } + else if( p_dialog->i_flags & DIALOG_LOGIN_PW_OK_CANCEL ) + { + msg_Dbg( p_intf, "dialog for login and pw requested" ); + [o_auth_title setStringValue: o_title]; + [o_auth_description setStringValue: o_description]; + [o_auth_login_fld setStringValue: @""]; + [o_auth_pw_fld setStringValue: @""]; + [NSApp beginSheet: o_auth_win modalForWindow: o_window + modalDelegate: self didEndSelector: nil contextInfo: nil]; + [o_auth_win makeKeyWindow]; + } + else if( p_dialog->i_flags & DIALOG_USER_PROGRESS ) + { + msg_Dbg( p_intf, "user progress dialog requested" ); + [o_prog_title setStringValue: o_title]; + [o_prog_description setStringValue: o_description]; + [o_prog_bar setDoubleValue: (double)p_dialog->val.f_float]; + if( p_dialog->i_timeToGo < 1 ) + [o_prog_timeToGo setStringValue: @""]; else - msg_Warn( p_intf, "requested dialog type not implemented yet" ); + [o_prog_timeToGo setStringValue: [NSString stringWithFormat: + _NS("Remaining time: %i seconds"), p_dialog->i_timeToGo]]; + [NSApp beginSheet: o_prog_win modalForWindow: o_window + modalDelegate: self didEndSelector: nil contextInfo: nil]; + [o_prog_win makeKeyWindow]; + } + else if( p_dialog->i_flags & DIALOG_PSZ_INPUT_OK_CANCEL ) + { + msg_Dbg( p_intf, "text input from user requested" ); + [o_input_title setStringValue: o_title]; + [o_input_description setStringValue: o_description]; + [o_input_fld setStringValue: @""]; + [NSApp beginSheet: o_input_win modalForWindow: o_window + modalDelegate: self didEndSelector: nil contextInfo: nil]; + [o_input_win makeKeyWindow]; } + else if( p_dialog->i_flags & DIALOG_INTF_PROGRESS ) + { + msg_Dbg( p_intf, "progress-bar in main intf requested" ); + [[VLCMain sharedInstance] setScrollField: o_description stopAfter: -1]; + [o_mainIntfPgbar setDoubleValue: (double)p_dialog->val.f_float]; + [o_mainIntfPgbar setHidden: NO]; + [[[VLCMain sharedInstance] getControllerWindow] makeKeyWindow]; + [o_mainIntfPgbar setIndeterminate: NO]; + } + else + msg_Err( p_intf, "requested dialog type unknown (%i)", p_dialog->i_flags ); } - (void)sheetDidEnd:(NSWindow *)o_sheet returnCode:(int)i_return contextInfo:(void *)o_context { - vlc_mutex_lock( &p_dialog->p_interaction->object_lock ); + vlc_object_lock( p_dialog->p_interaction ); if( i_return == NSAlertDefaultReturn ) { p_dialog->i_return = DIALOG_OK_YES; } - else if( i_return == NSAlertAlternateReturn && ( p_dialog->i_flags & DIALOG_OK_CANCEL ) ) - { - p_dialog->i_return = DIALOG_CANCELLED; - } else if( i_return == NSAlertAlternateReturn ) { p_dialog->i_return = DIALOG_NO; @@ -213,52 +262,233 @@ p_dialog->i_return = DIALOG_CANCELLED; } p_dialog->i_status = ANSWERED_DIALOG; - vlc_mutex_unlock( &p_dialog->p_interaction->object_lock ); + vlc_object_unlock( p_dialog->p_interaction ); } -(void)updateDialog { - int i = 0; - for( i = 0 ; i< p_dialog->i_widgets; i++ ) + if( p_dialog->i_flags & DIALOG_USER_PROGRESS ) { - if( p_dialog->i_type & WIDGET_PROGRESS ) + [o_prog_description setStringValue: + [NSString stringWithUTF8String: p_dialog->psz_description]]; + [o_prog_bar setDoubleValue: (double)p_dialog->val.f_float]; + + if( [o_prog_bar doubleValue] == 100.0 ) { - [o_prog_bar setDoubleValue: \ - (double)(p_dialog->pp_widgets[i]->val.f_float)]; + /* we are done, let's hide */ + [self hideDialog]; + } - if( [o_prog_bar doubleValue] == 100.0 ) - { - /* we are done, let's hide */ - [self hideDialog]; - return; - } + if( p_dialog->i_timeToGo < 1 ) + [o_prog_timeToGo setStringValue: @""]; + else + [o_prog_timeToGo setStringValue: [NSString stringWithFormat: + _NS("Remaining time: %i seconds"), p_dialog->i_timeToGo]]; + + return; + } + if( p_dialog->i_flags & DIALOG_INTF_PROGRESS ) + { + [[VLCMain sharedInstance] setScrollField: + [NSString stringWithUTF8String: p_dialog->psz_description] + stopAfter: -1]; + [o_mainIntfPgbar setDoubleValue: (double)p_dialog->val.f_float]; + + if( [o_mainIntfPgbar doubleValue] == 100.0 ) + { + /* we are done, let's hide */ + [self hideDialog]; } + return; } } -(void)hideDialog { - msg_Dbg( p_intf, "hide event" ); - if( p_dialog->i_type & WIDGET_PROGRESS ) + msg_Dbg( p_intf, "hide event %p", self ); + if( p_dialog->i_flags & DIALOG_USER_PROGRESS ) + { + if([o_prog_win isVisible]) + { + [NSApp endSheet: o_prog_win]; + [o_prog_win close]; + } + } + if( p_dialog->i_flags & DIALOG_LOGIN_PW_OK_CANCEL ) + { + if([o_auth_win isVisible]) + { + [NSApp endSheet: o_auth_win]; + [o_auth_win close]; + } + } + if( p_dialog->i_flags & DIALOG_PSZ_INPUT_OK_CANCEL ) + { + if([o_input_win isVisible]) + { + [NSApp endSheet: o_input_win]; + [o_input_win close]; + } + } + if( p_dialog->i_flags & DIALOG_INTF_PROGRESS ) { - [NSApp endSheet: o_prog_win]; - [o_prog_win close]; + [o_mainIntfPgbar setIndeterminate: YES]; + [o_mainIntfPgbar setHidden: YES]; + [[VLCMain sharedInstance] resetScrollField]; } } -(void)destroyDialog { msg_Dbg( p_intf, "destroy event" ); + if( o_mainIntfPgbar ) + [o_mainIntfPgbar release]; } - (IBAction)cancelAndClose:(id)sender { - /* tell the core that the dialog was cancelled */ - vlc_mutex_lock( &p_dialog->p_interaction->object_lock ); + /* tell the core that the dialog was cancelled in a yes/no-style dialogue */ + vlc_object_lock( p_dialog->p_interaction ); p_dialog->i_return = DIALOG_CANCELLED; p_dialog->i_status = ANSWERED_DIALOG; - vlc_mutex_unlock( &p_dialog->p_interaction->object_lock ); + vlc_object_unlock( p_dialog->p_interaction ); msg_Dbg( p_intf, "dialog cancelled" ); } +- (IBAction)cancelDialog:(id)sender +{ + /* tell core that the user wishes to cancel the dialogue + * Use this function if cancelling is optionally like in the progress-dialogue */ + vlc_object_lock( p_dialog->p_interaction ); + p_dialog->b_cancelled = true; + vlc_object_unlock( p_dialog->p_interaction ); + msg_Dbg( p_intf, "cancelling dialog, will close it later on" ); +} + +- (IBAction)okayAndClose:(id)sender +{ + msg_Dbg( p_intf, "running okayAndClose" ); + vlc_object_lock( p_dialog->p_interaction ); + if( p_dialog->i_flags == DIALOG_LOGIN_PW_OK_CANCEL ) + { + p_dialog->psz_returned[0] = strdup( [[o_auth_login_fld stringValue] UTF8String] ); + p_dialog->psz_returned[1] = strdup( [[o_auth_pw_fld stringValue] UTF8String] ); + } + else if( p_dialog->i_flags == DIALOG_PSZ_INPUT_OK_CANCEL ) + p_dialog->psz_returned[0] = strdup( [[o_input_fld stringValue] UTF8String] ); + p_dialog->i_return = DIALOG_OK_YES; + p_dialog->i_status = ANSWERED_DIALOG; + vlc_object_unlock( p_dialog->p_interaction ); + msg_Dbg( p_intf, "dialog acknowledged" ); +} + +@end + +/***************************************************************************** + * VLCErrorInteractionPanel implementation + *****************************************************************************/ +@implementation VLCErrorInteractionPanel +-(id)init +{ + [super init]; + + /* load the nib */ + nib_interact_errpanel_loaded = [NSBundle loadNibNamed:@"InteractionErrorPanel" owner:self]; + + /* init strings */ + [o_window setTitle: _NS("Errors and Warnings")]; + [o_cleanup_button setTitle: _NS("Clean up")]; + [o_messages_btn setTitle: _NS("Show Details")]; + + /* init data sources */ + o_errors = [[NSMutableArray alloc] init]; + o_icons = [[NSMutableArray alloc] init]; + + return self; +} + +-(void)dealloc +{ + [o_errors release]; + [o_icons release]; + [super dealloc]; +} + +-(void)showPanel +{ + [o_window makeKeyAndOrderFront: self]; +} + +-(void)addError: (NSString *)o_error withMsg:(NSString *)o_msg +{ + /* format our string as desired */ + NSMutableAttributedString * ourError; + ourError = [[NSMutableAttributedString alloc] initWithString: + [NSString stringWithFormat:@"%@\n%@", o_error, o_msg] + attributes: + [NSDictionary dictionaryWithObject: [NSFont systemFontOfSize:11] forKey: NSFontAttributeName]]; + [ourError + addAttribute: NSFontAttributeName + value: [NSFont boldSystemFontOfSize:11] + range: NSMakeRange( 0, [o_error length])]; + [o_errors addObject: ourError]; + [ourError release]; + + [o_icons addObject: [NSImage imageWithErrorIcon]]; + + [o_error_table reloadData]; +} + +-(void)addWarning: (NSString *)o_warning withMsg:(NSString *)o_msg +{ + /* format our string as desired */ + NSMutableAttributedString * ourWarning; + ourWarning = [[NSMutableAttributedString alloc] initWithString: + [NSString stringWithFormat:@"%@\n%@", o_warning, o_msg] + attributes: + [NSDictionary dictionaryWithObject: [NSFont systemFontOfSize:11] forKey: NSFontAttributeName]]; + [ourWarning + addAttribute: NSFontAttributeName + value: [NSFont boldSystemFontOfSize:11] + range: NSMakeRange( 0, [o_warning length])]; + [o_errors addObject: ourWarning]; + [ourWarning release]; + + [o_icons addObject: [NSImage imageWithWarningIcon]]; + + [o_error_table reloadData]; +} + +-(IBAction)cleanupTable:(id)sender +{ + [o_errors removeAllObjects]; + [o_icons removeAllObjects]; + [o_error_table reloadData]; +} + +-(IBAction)showMessages:(id)sender +{ + [[VLCMain sharedInstance] showMessagesPanel: sender]; +} + +/*---------------------------------------------------------------------------- + * data source methods + *---------------------------------------------------------------------------*/ +- (int)numberOfRowsInTableView:(NSTableView *)theDataTable +{ + return [o_errors count]; +} + +- (id)tableView:(NSTableView *)theDataTable objectValueForTableColumn: + (NSTableColumn *)theTableColumn row: (int)row +{ + if( [[theTableColumn identifier] isEqualToString: @"error_msg"] ) + return [o_errors objectAtIndex: row]; + + if( [[theTableColumn identifier] isEqualToString: @"icon"] ) + return [o_icons objectAtIndex: row]; + + return @"unknown identifier"; +} + @end