/* * Grouch.app Copyright (C) 2006 Andy Sveikauskas * ------------------------------------------------------------------------ * This program is free software under the GNU General Public License * -- * GUI for buddy list. */ #import #import #import #import #import #import #import @implementation BuddyList + windowWithInstance:(ClientInstance*)c { return [[self new] initWithInstance:c]; } - initWithInstance:(ClientInstance*)c { cli = c; [NSBundle loadGSMarkupNamed:@"ContextMenu.Buddy" owner:self]; [window orderFront:nil]; [window makeKeyWindow]; [NSBundle loadGSMarkupNamed:@"BuddyListWindow" owner:self]; [window setTitle:[NSString stringWithFormat:@"%@%@", [window title], [cli nick]]]; [[[outlineView tableColumns] objectAtIndex:0] setEditable:NO]; [outlineView setDataSource:self]; return self; } - (void)dealloc { if( window ) [window performClose:self]; if( list ) [list release]; [contextMenu release]; [super dealloc]; } - (BOOL)windowShouldClose:sender { int row; for( row=0; row<[outlineView numberOfRows]; ++row ) { id item = [outlineView itemAtRow:row]; if( [outlineView isExpandable:item] ) [outlineView collapseItem:item]; } if( list ) [list release]; list = nil; [outlineView reloadData]; [outlineView release]; // XXX reloadData]; [window autorelease]; window = nil; [cli logOff]; return YES; } - getActiveUser { int row = [outlineView selectedRow]; if( row >= 0 ) { id r = [outlineView itemAtRow:row]; if( r && [(NSObject*)r isKindOfClass:[User class]] ) return r; } return nil; } - getActiveClient { return cli; } - getActiveListItem { int row = [outlineView selectedRow]; return (row >= 0) ? [outlineView itemAtRow:row] : nil; } - (void)reloadData:(BOOL)newList { NSMutableDictionary *expansions = [NSMutableDictionary new]; int row = [outlineView selectedRow]; id selection = nil; NSObject *selectionValue = nil; // Save currently selected item if( row >= 0 ) { selection = [outlineView itemAtRow:row]; if( selection ) { selectionValue = [[[outlineView dataSource] outlineView:outlineView objectValueForTableColumn:nil byItem:selection] retain]; } } // Save expansion settings if (newList) for( row=0; row<[outlineView numberOfRows]; ++row ) { id item = [outlineView itemAtRow:row]; if( [outlineView isExpandable:item] ) { BOOL ex = [outlineView isItemExpanded:item]; [expansions setObject:[NSNumber numberWithInt: ex?1:0] forKey:[[outlineView dataSource] outlineView:outlineView objectValueForTableColumn:nil byItem:item]]; [outlineView collapseItem:item]; } } // Ask for a new copy of the buddy list if necessary if( newList ) { if( list ) [list release]; list = [[cli session] getContactList:NO]; if( !list ) list = [NSArray array]; [list retain]; } // This clobbers all the data saved above. [outlineView reloadData]; [outlineView deselectAll:self]; // So we restore it. for( row=0; row<[outlineView numberOfRows]; ++row ) { id item = [outlineView itemAtRow:row]; id key = [[outlineView dataSource] outlineView:outlineView objectValueForTableColumn:nil byItem:item]; // Restore expansion junk. if( newList && [outlineView isExpandable:item] ) { NSNumber *value = [expansions objectForKey:key]; BOOL expand = !value || [value intValue]; if( expand ) [outlineView expandItem:item]; else [outlineView collapseItem:item]; // Our item might have changed from expand/collapse. item = [outlineView itemAtRow:row]; key = [[outlineView dataSource] outlineView:outlineView objectValueForTableColumn:nil byItem:item]; } // Is this our selection? if( selection == item || [selectionValue isEqual:key] ) [outlineView selectRow:row byExtendingSelection:NO]; } [expansions release]; if( selectionValue ) [selectionValue release]; } - outlineView:view child:(int)index ofItem:(NSArray*)item { if( !item ) return [list objectAtIndex:index]; else return [item objectAtIndex:index+1]; } - (int)outlineView:view numberOfChildrenOfItem:item { if( !item ) return list ? [list count] : 0; else if( [(NSObject*)item isKindOfClass:[NSArray class]] ) return [(NSArray*)item count] - 1; else return 0; } - (BOOL)outlineView:view isItemExpandable:item { return item && [(NSObject*)item isKindOfClass:[NSArray class]]; } - outlineView:view objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:item { if( [(NSObject*)item isKindOfClass:[NSArray class]] ) item = [(NSArray*)item objectAtIndex:0]; if( [(NSObject*)item isKindOfClass:[User class]] ) return [(User*)item attributedStringValue]; else { NSString *tag = [Defaults get:@"normal" fromDict:@"Buddy List Tags"]; return [[NSString stringWithFormat:@"%@%@", tag?tag:@"", item] parseHtml]; } } - (void)recurse:(NSMutableArray*)r group:(NSArray*)group { int i; [r addObject:[group objectAtIndex:0]]; for( i=1; i<[group count]; ++i ) { NSObject *obj = [group objectAtIndex:i]; if( [obj isKindOfClass:[NSArray class]] ) [self recurse:r group:(NSArray*)obj]; } } - (NSArray*)getGroups { NSMutableArray *r = [NSMutableArray array]; int i; for( i=0; list && i<[list count]; ++i ) { NSObject *obj = [list objectAtIndex:i]; if( [obj isKindOfClass:[NSArray class]] ) [self recurse:r group:(NSArray*)obj]; } return r; } - (void)doubleClick:sender { User *u = [self getActiveUser]; if(u) [u createWindow]; } - outlineView:view contextMenuForItem:item { [window makeKeyAndOrderFront:self]; return contextMenu; } @end