X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2Finteraction.m;h=c62e36c4fcb93f38ac78b9ac9b0faac0074d3854;hb=8a5d95d032dd1d3773858ece1d5efe2f970d6bab;hp=48ad4ea7c4314f0fe2bf8d676d79a26426c57593;hpb=415518de9afd158cc5090a1b602049fed8b6637f;p=vlc diff --git a/modules/gui/macosx/interaction.m b/modules/gui/macosx/interaction.m index 48ad4ea7c4..c62e36c4fc 100644 --- a/modules/gui/macosx/interaction.m +++ b/modules/gui/macosx/interaction.m @@ -1,16 +1,17 @@ /***************************************************************************** * interaction.h: Mac OS X interaction dialogs ***************************************************************************** - * Copyright (C) 2001-2005 the VideoLAN team - * $Id: vout.h 13803 2005-12-18 18:54:28Z bigben $ + * Copyright (C) 2005-2007 the VideoLAN team + * $Id$ * * Authors: Derk-Jan Hartman + * Felix Kühne * * This program is free software; you can redistribute it and/or modify * 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 @@ -18,11 +19,15 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ -#include "intf.h" -#import +#import "intf.h" +#import "interaction.h" +#import "misc.h" + +/* for the icons in our custom error panel */ +#import /***************************************************************************** * VLCInteractionList implementation @@ -38,6 +43,8 @@ name: @"VLCNewInteractionEventNotification" object:self]; + o_error_panel = [[VLCErrorInteractionPanel alloc] init]; + return self; } @@ -71,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]; @@ -84,6 +90,11 @@ [o_interaction_list removeObject:o_interaction]; } +-(id)getErrorPanel +{ + return o_error_panel; +} + -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; @@ -91,7 +102,6 @@ [o_interaction_list release]; [super dealloc]; } - @end /***************************************************************************** @@ -101,6 +111,7 @@ -(id)initDialog: (interaction_dialog_t *)_p_dialog { + p_intf = VLCIntf; [super init]; p_dialog = _p_dialog; return self; @@ -108,14 +119,30 @@ -(void)runDialog { - int i = 0; id o_window = NULL; if( !p_dialog ) - NSLog( @"serious issue" ); + msg_Err( p_intf, "no available interaction framework" ); + + if( !nib_interact_loaded ) + { + 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 : _("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; - NSString *o_title = [NSString stringWithUTF8String:p_dialog->psz_title ? p_dialog->psz_title : "title"]; - NSString *o_description = [NSString stringWithUTF8String:p_dialog->psz_description ? p_dialog->psz_description : "desc"]; - vout_thread_t *p_vout = vlc_object_find( VLCIntf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); if( p_vout != NULL ) { @@ -123,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; @@ -135,49 +162,97 @@ { o_window = [NSApp mainWindow]; } - - NSLog( @"Title: %@", o_title ); - NSLog( @"Description: %@", o_description ); - if( p_dialog->i_id == DIALOG_ERRORS ) + +#if 0 + msg_Dbg( p_intf, "Title: %s", [o_title UTF8String] ); + msg_Dbg( p_intf, "Description: %s", [o_description UTF8String] ); + 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++ ) - { - NSLog( @"Error: %@", [NSString stringWithUTF8String: 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++ ) - { - NSLog( @"widget: %@", [NSString stringWithUTF8String: p_dialog->pp_widgets[i]->psz_text] ); - } - if( p_dialog->i_flags & 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 ) - { - NSBeginInformationalAlertSheet( o_title, @"Yes" , @"No", @"Cancel", o_window, self, - @selector(sheetDidEnd: returnCode: contextInfo:), NULL, nil, o_description ); - } + 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 - NSLog( @"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; @@ -187,27 +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 { - NSLog( @"update event" ); + if( p_dialog->i_flags & DIALOG_USER_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 ) + { + /* we are done, let's hide */ + [self hideDialog]; + } + + 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 { - NSLog( @"hide event" ); + 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 ) + { + [o_mainIntfPgbar setIndeterminate: YES]; + [o_mainIntfPgbar setHidden: YES]; + [[VLCMain sharedInstance] resetScrollField]; + } } -(void)destroyDialog { - NSLog( @"destroy event" ); + msg_Dbg( p_intf, "destroy event" ); + if( o_mainIntfPgbar ) + [o_mainIntfPgbar release]; +} + +- (IBAction)cancelAndClose:(id)sender +{ + /* 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_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]; } -@end \ No newline at end of file +-(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