/* * Grouch.app Copyright (C) 2006 Andy Sveikauskas * ------------------------------------------------------------------------ * This program is free software under the GNU General Public License * -- * User structure. This also involves UI code for IM windows. */ #import #import #import #import #import #import #import #import @implementation User + userWithName:(NSString*)n forClient:(ClientInstance*)c { return [[[User new] initWithName:n forClient:c] autorelease]; } - initWithName:(NSString*)n forClient:(ClientInstance*)c { [super init]; [name=n retain]; cli = c; window = nil; chatRooms = [NSMutableDictionary new]; return self; } - (void)dealloc { if( window ) [window performClose:self]; if( originalWindowTitle ) [originalWindowTitle release]; [chatRooms release]; [name release]; if( alias ) [alias release]; [super dealloc]; } - (void)setTitle { if( window ) { NSString *a = [self alias]; if( ![a isEqual:name] ) a = [NSString stringWithFormat:@"%@ (%@)", a, name]; [window setTitle:[NSString stringWithFormat:@"%@%@", originalWindowTitle, a]]; } } - (void)setNick:(NSString*)n { if( name != n && ![n isEqual:name] ) { if( name ) [name release]; [name=n retain]; [self reloadData]; [self setTitle]; } } - (void)setAlias:(NSString*)a { if( alias != a && ![a isEqual:alias] ) { if( alias ) [alias release]; if( (alias=a) ) [alias retain]; [self reloadData]; [self setTitle]; } } - (void)message:(NSString*)s withFlags:(GrouchMessageFlags)f { [self createWindow]; [self append:[cli formatMessage:s from:name withFlags:f]]; if( !(f&GrouchMessageReflect) ) [cli processAutoReply:name]; // Make OS X's Dock bounce until focus. [NSApp requestUserAttention:NSCriticalRequest]; } - (void)append:(NSAttributedString*)str { NSTextStorage *text = [output textStorage]; [text beginEditing]; [text appendAttributedString:str]; [text appendAttributedString:[@" \n" attributed]]; [text endEditing]; // XXX: this should be conditional and work with scrolling widgets... // but I couldn't get that to work. [output moveToEndOfDocument:output]; [output scrollRangeToVisible:[output selectedRange]]; } - (void)createWindow { if( !window ) { if( originalWindowTitle ) [originalWindowTitle release]; [NSBundle loadGSMarkupNamed:@"MsgWindow" owner:self]; originalWindowTitle = [[window title] retain]; [self setTitle]; [cli addDependentWindow:window]; [input setDefaultFont]; } [window orderFront:nil]; [window makeKeyWindow]; } - (void)textIn { NSString *msg; if( !cli ) return; [[input textStorage] inferLinks]; msg = [[input textStorage] generateHtml]; if( [msg length] ) { id ses = [cli session]; [ses sendMessage:msg to:name withFlags:GrouchMessageReflect]; [[input textStorage] deleteCharactersInRange: NSMakeRange(0, [[input textStorage] length])]; } [window makeFirstResponder:input]; } - (BOOL)windowShouldClose:sender { if( cli ) [cli removeDependentWindow:window]; [window autorelease]; [scroll release]; [output release]; [input release]; window = nil; scroll = nil; output = nil; input = nil; if( !cli ) [self release]; return YES; } - (BOOL)windowShouldDetach:sender { [self retain]; cli = nil; return YES; } - (BOOL)mayRelease { return !window && [self retainCount] <= 1 && ![chatRooms count]; } - (void)joinChat:(NSString*)room { [chatRooms setObject:room forKey:[room screenNameKey]]; } - (void)partChat:(NSString*)room { [chatRooms removeObjectForKey:[room screenNameKey]]; } - (NSString*)name { return name; } - (NSString*)alias { return alias ? alias : name; } - (BOOL)online { return online; } - (void)online:(BOOL)on { online = on; } - (time_t)onlineSince { return onlineSince; } - (void)idle:(time_t)t { idle = t; } - (time_t)idle { return idle; } - (void)away:(BOOL)a { away = a; } - (BOOL)away { return away; } - (void)warn:(int)w { warn = w; } - (int)warn { return warn; } - (void)onlineSince:(time_t)t { onlineSince = t; } - getActiveUser { return cli ? self : nil; } - getActiveClient { return cli; } - (ClientInstance*)instance { return cli; } - (NSAttributedString*)attributedStringValue { NSString *state = online ? away ? (idle ? @"away+idle":@"away") : idle ? @"idle" : @"normal" : @"offline"; NSString *html = [Defaults get:state fromDict:@"Buddy List Tags"]; NSMutableString *append = [NSMutableString string]; NSString *plain = [self alias]; if( away ) [append appendString:[GrouchString getString:@"away"]]; if( warn ) [append appendString:[NSString stringWithFormat:@" (%i%%)", warn]]; return [[NSString stringWithFormat:@"%@%@%@", html?html:@"", plain?plain:@"", append] parseHtml]; } // Logical Xor. #define XOR(a,b) ((a?1:0) ^ (b?1:0)) - (void)reloadData { NSEnumerator *e = [chatRooms objectEnumerator]; NSString *c; while( (c = [e nextObject]) ) [[cli getChannel:c] reloadData]; if( [self retainCount] > 1 ) [cli reloadData:XOR(online,lastOnlineStatus)]; lastOnlineStatus = online; } @end