/* * Grouch.app Copyright (C) 2006 Andy Sveikauskas * ------------------------------------------------------------------------ * This program is free software under the GNU General Public License * -- * Chat room interface. */ #import #import #import #import #import #import #import #import @protocol ChannelPrivate - (id)tableView:tbl objectValueForTableColumn:col row:(int)i raw:(BOOL)raw; @end @implementation Channel + channelForRoom:(NSString*)roomName andClient:(ClientInstance*)inst { return [[[self alloc] initForRoom:roomName andClient:inst] autorelease]; } - initForRoom:(NSString*)roomName andClient:(ClientInstance*)inst { [super init]; cli = inst; [room=roomName retain]; users = [NSMutableDictionary new]; return self; } - (void)dealloc { if( window ) [window performClose:self]; [self removeUsers]; [users release]; [room release]; [contextMenu release]; [super dealloc]; } - (void)welcome { if( !window ) { [NSBundle loadGSMarkupNamed:@"ContextMenu.Chat" owner:self]; [NSBundle loadGSMarkupNamed:@"ChatWindow" owner:self]; [window orderFront:nil]; [window makeKeyWindow]; [window setTitle:[NSString stringWithFormat:@"%@%@", [window title], room]]; [[[tableView tableColumns] objectAtIndex:0] setEditable:NO]; [tableView setDataSource:self]; [cli addDependentWindow:window]; [input setDefaultFont]; } } - (void)bye { [self removeUsers]; haveLeft = YES; if( window ) { [self retain]; [cli removeDependentWindow:window]; } cli = nil; } - (void)join:(NSString*)usr { NSString *key = [usr screenNameKey]; User *u = (id)[cli getUser:usr]; User *preExisting = [users objectForKey:key]; if( preExisting ) [preExisting partChat:room]; [users setObject:u forKey:key]; [u joinChat:room]; [self reloadData]; } - (void)part:(NSString*)usr { NSString *key = [usr screenNameKey]; User *u = [users objectForKey:key]; if( u ) { [u partChat:room]; [users removeObjectForKey:key]; [self reloadData]; } } - (void)reloadData { if( window ) [tableView reloadData]; } - (BOOL)windowShouldClose:sender { [window autorelease]; window = nil; [scroll release]; [output release]; [input release]; [tableView release]; if( cli && !haveLeft ) { id ses = [cli session]; [ses partChannel:room]; haveLeft = YES; } if( !cli ) [self release]; return YES; } - (BOOL)windowShouldDetach:sender { [self bye]; return YES; } - (void)message:(NSString*)msg from:(NSString*)user withFlags:(GrouchMessageFlags)flags { if( !window ) { NSLog(@"Warning: got message before Channel-welcome"); return; } [self append:[cli formatMessage:msg from:user withFlags:flags]]; } - (void)append:(NSAttributedString*)str { NSTextStorage *text = [output textStorage]; [text beginEditing]; [text appendAttributedString:str]; [text appendAttributedString:[@" \n" attributed]]; [text endEditing]; } - (void)textIn { NSString *msg; if( !cli ) return; [[input textStorage] inferLinks]; msg = [[input textStorage] generateHtml]; if( [msg length] ) { id ses = [cli session]; [ses sendMessage:msg toChannel:room withFlags:GrouchMessageReflect]; [[input textStorage] deleteCharactersInRange: NSMakeRange(0, [[input textStorage] length])]; } [window makeFirstResponder:input]; } - (void)removeUsers { NSEnumerator *e; User *u; if( users ) { e = [users objectEnumerator]; while( (u=[e nextObject]) ) [u partChat:room]; [users release]; users = [NSMutableDictionary new]; } [self reloadData]; } - (BOOL)mayRelease { return !window && ![users count]; } - getActiveClient { return cli; } - getActiveUser { if( cli && window ) { int row = [tableView selectedRow]; if( row >= 0 ) { id ds = [tableView dataSource]; return ds ? [ds tableView:tableView objectValueForTableColumn:nil row:row raw:YES] : ds; } } return nil; } - (int)numberOfRowsInTableView:tbl { return [users count]; } - (id)tableView:tbl objectValueForTableColumn:col row:(int)i raw:(BOOL)raw { NSEnumerator *e = [users objectEnumerator]; User *u = nil; do { u = [e nextObject]; } while( i-- ); return raw ? (id)u : (u ? (id)[u attributedStringValue] : nil); } - (id)tableView:tbl objectValueForTableColumn:col row:(int)i { id s = (id)self; return [s tableView:tbl objectValueForTableColumn:col row:i raw:NO]; } - (void)doubleClick:sender { User *u = [self getActiveUser]; if(u) [u createWindow]; } - tableView:tbl contextMenuForRow:(int)row col:(int)col { [window makeKeyAndOrderFront:self]; return contextMenu; } @end