Changeset 2224

Show
Ignore:
Timestamp:
01/08/05 23:27:28 (4 years ago)
Author:
timothy
Message:

* Previous info panels work again. Panels need redone to support SILC and other things better.
* More clean up of code.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/JVChatMemberInspector.h

    r1823 r2224  
    2828        IBOutlet NSButton *requestInfo; 
    2929        JVChatRoomMember *_member; 
    30         BOOL _localOnly; 
     30        NSTimer *_localTimeUpdateTimer; 
     31        NSTimer *_updateTimer; 
    3132        BOOL _nibLoaded; 
    32         BOOL _classSet; 
    3333        BOOL _addressResolved; 
    34         BOOL _whoisComplete; 
    3534} 
    3635- (id) initWithChatMember:(JVChatRoomMember *) member; 
    3736 
    38 - (void) setFetchLocalServerInfoOnly:(BOOL) localOnly; 
    39  
    40 - (IBAction) sendPing:(id) sender; 
    4137- (IBAction) requestLocalTime:(id) sender; 
    4238- (IBAction) requestClientInfo:(id) sender; 
  • trunk/JVChatMemberInspector.m

    r2193 r2224  
    11#import <ChatCore/MVChatConnection.h> 
     2#import <ChatCore/MVChatUser.h> 
     3#import <ChatCore/MVChatRoom.h> 
    24#import "JVChatMemberInspector.h" 
     5#import "JVChatRoom.h" 
    36#import "JVBuddy.h" 
    47#import "MVFileTransferController.h" 
     
    69@implementation JVChatRoomMember (JVChatRoomMemberInspection) 
    710- (id <JVInspector>) inspector { 
    8         return nil; //[[[JVChatMemberInspector alloc] initWithChatMember:self] autorelease]; 
     11        return [[[JVChatMemberInspector alloc] initWithChatMember:self] autorelease]; 
    912} 
    1013@end 
     
    1619        if( ( self = [self init] ) ) { 
    1720                _member = [member retain]; 
    18                 _localOnly = NO; 
    19 //              [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( gotUserWhois: ) name:MVChatConnectionGotUserWhoisNotification object:[_member connection]]; 
    20 //              [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( gotUserServer: ) name:MVChatConnectionGotUserServerNotification object:[_member connection]]; 
    21 //              [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( gotUserChannels: ) name:MVChatConnectionGotUserChannelsNotification object:[_member connection]]; 
    22 //              [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( gotUserOperator: ) name:MVChatConnectionGotUserOperatorNotification object:[_member connection]]; 
    23 //              [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( gotUserIdle: ) name:MVChatConnectionGotUserIdleNotification object:[_member connection]]; 
    24 //              [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( gotUserWhoisComplete: ) name:MVChatConnectionGotUserWhoisCompleteNotification object:[_member connection]]; 
    25 //              [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( gotAwayStatus: ) name:MVChatConnectionUserAwayStatusNotification object:[_member connection]]; 
    26                 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( errorOccurred : ) name:MVChatConnectionErrorNotification object:[_member connection]]; 
    27                 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( gotCTCPResponse: ) name:MVChatConnectionSubcodeReplyNotification object:[_member connection]]; 
     21                _localTimeUpdateTimer = nil; 
     22                _updateTimer = [[NSTimer scheduledTimerWithTimeInterval:30. target:self selector:@selector( updateInformation ) userInfo:nil repeats:YES] retain]; 
    2823        } 
    2924        return self; 
     25} 
     26 
     27- (void) release { 
     28        if( ( [self retainCount] - ( _localTimeUpdateTimer ? 2 : 1 ) ) == 1 ) { 
     29                [_localTimeUpdateTimer invalidate]; 
     30                [_updateTimer invalidate]; 
     31        } 
     32        [super release]; 
    3033} 
    3134 
     
    3336        [[NSNotificationCenter defaultCenter] removeObserver:self]; 
    3437 
     38        [_localTimeUpdateTimer release]; 
     39        [_updateTimer release]; 
    3540        [_member release]; 
     41 
     42        _localTimeUpdateTimer = nil; 
     43        _updateTimer = nil; 
    3644        _member = nil; 
    3745 
     
    5967 
    6068- (void) willLoad { 
     69        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( infoUpdated: ) name:MVChatUserInformationUpdatedNotification object:[_member user]]; 
     70        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( attributeUpdated: ) name:MVChatUserAttributeUpdatedNotification object:[_member user]]; 
     71 
     72        [[_member user] refreshInformation]; 
    6173        [progress startAnimation:nil]; 
    62         _whoisComplete = NO; 
    6374        _addressResolved = NO; 
    64         _classSet = NO; 
    6575        [nickname setObjectValue:[_member nickname]]; 
    6676        if( [[_member buddy] picture] ) [image setImage:[[_member buddy] picture]]; 
    67 //      [[_member connection] fetchInformationForUser:[_member nickname] withPriority:NO fromLocalServer:_localOnly]; 
    6877} 
    6978 
    7079#pragma mark - 
    7180 
    72 - (void) setFetchLocalServerInfoOnly:(BOOL) localOnly { 
    73         _localOnly = localOnly; 
     81- (void) updateInformation { 
     82        [[_member user] refreshInformation];     
     83        [progress startAnimation:nil]; 
    7484} 
     85 
     86#pragma mark - 
    7587 
    7688- (void) gotAddress:(NSString *) ip { 
     
    7890        [address setToolTip:( ip ? ip : nil )]; 
    7991        _addressResolved = YES; 
    80         if (_whoisComplete) 
    81                 [progress stopAnimation:nil]; 
     92        [progress stopAnimation:nil]; 
    8293} 
    8394 
    84 - (oneway void) lookupAddress:(NSString *) host
     95- (oneway void) lookupAddress
    8596        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    86         NSString *ip = [[NSHost hostWithName:host] address]; 
    87         [self performSelectorOnMainThread:@selector(gotAddress:) withObject:ip waitUntilDone:YES]; 
     97        NSString *ip = [[NSHost hostWithName:[[_member user] address]] address]; 
     98        [self performSelectorOnMainThread:@selector( gotAddress: ) withObject:ip waitUntilDone:YES]; 
    8899        [pool release]; 
    89100} 
    90101 
    91 /*- (void) gotUserInfo:(NSNotification *) notification { 
    92         if( [[[notification userInfo] objectForKey:@"who"] caseInsensitiveCompare:[_member nickname]] != NSOrderedSame ) return; 
    93         NSDictionary *info = [[notification userInfo] objectForKey:@"info"]; 
    94         NSString *clas = nil; 
    95         if( [[info objectForKey:@"flags"] intValue] == 0 ) { 
    96                 clas = NSLocalizedString( @"Restricted user", "restricted user class" ); 
    97         } else if( [[info objectForKey:@"flags"] intValue] & 0x02 ) { 
    98                 clas = NSLocalizedString( @"Normal user", "normal user class" ); 
    99         } else if( [[info objectForKey:@"flags"] intValue] & 0x04 ) { 
    100                 clas = NSLocalizedString( @"Server operator", "server operator class" ); 
     102- (void) infoUpdated:(NSNotification *) notification { 
     103        if( [[_member user] isIdentified] ) { 
     104                [class setObjectValue:NSLocalizedString( @"Registered user", "registered user class" )]; 
     105        } else if( [[_member user] isServerOperator] ) { 
     106                [class setObjectValue:NSLocalizedString( @"Server operator", "server operator class" )]; 
     107        } else { 
     108                [class setObjectValue:NSLocalizedString( @"Normal user", "normal user class" )]; 
    101109        } 
    102         [class setObjectValue:clas]; 
    103         [username setObjectValue:[info objectForKey:@"username"]]; 
    104         [hostname setObjectValue:[info objectForKey:@"hostname"]]; 
    105         [hostname setToolTip:[info objectForKey:@"hostname"]]; 
    106         [NSThread detachNewThreadSelector:@selector( lookupAddress: ) toTarget:self withObject:[[[info objectForKey:@"hostname"] copy] autorelease]]; 
    107         [server setObjectValue:[info objectForKey:@"server"]]; 
    108         [realName setObjectValue:[info objectForKey:@"realName"]]; 
    109         [realName setToolTip:[info objectForKey:@"realName"]]; 
    110         [connected setObjectValue:MVReadableTime( [[info objectForKey:@"connected"] doubleValue], YES )]; 
    111         [idle setObjectValue:MVReadableTime( [[NSDate date] timeIntervalSince1970] + [[info objectForKey:@"idle"] doubleValue], YES )]; 
    112 }*/ 
    113110 
    114 - (void) gotUserWhois:(NSNotification *) notification { 
    115         if( [[[notification userInfo] objectForKey:@"who"] caseInsensitiveCompare:[_member nickname]] != NSOrderedSame ) return; 
    116         [username setObjectValue:[[notification userInfo] objectForKey:@"username"]]; 
    117         [hostname setObjectValue:[[notification userInfo] objectForKey:@"hostname"]]; 
    118         [hostname setToolTip:[[notification userInfo] objectForKey:@"hostname"]]; 
    119         [NSThread detachNewThreadSelector:@selector( lookupAddress: ) toTarget:self withObject:[[[[notification userInfo] objectForKey:@"hostname"] copy] autorelease]]; 
    120         [realName setObjectValue:[[notification userInfo] objectForKey:@"realname"]]; 
    121         [realName setToolTip:[[notification userInfo] objectForKey:@"realname"]]; 
     111        [username setObjectValue:[[_member user] username]]; 
     112 
     113        [hostname setObjectValue:[[_member user] address]]; 
     114        [hostname setToolTip:[[_member user] address]]; 
     115 
     116        if( ! _addressResolved ) [NSThread detachNewThreadSelector:@selector( lookupAddress ) toTarget:self withObject:nil]; 
     117 
     118        [server setObjectValue:[[_member user] serverAddress]]; 
     119        [server setToolTip:[[_member user] serverAddress]]; 
     120 
     121        [realName setObjectValue:[[_member user] realName]]; 
     122        [realName setToolTip:[[_member user] realName]]; 
     123 
     124        [connected setObjectValue:MVReadableTime( [[[_member user] dateConnected] timeIntervalSince1970], YES )]; 
     125        [idle setObjectValue:MVReadableTime( [[NSDate date] timeIntervalSince1970] + [[_member user] idleTime], YES )]; 
     126 
     127        if( _addressResolved ) [progress stopAnimation:nil]; 
    122128} 
    123129 
    124 - (void) gotUserServer:(NSNotification *) notification { 
    125         if( [[[notification userInfo] objectForKey:@"who"] caseInsensitiveCompare:[_member nickname]] != NSOrderedSame ) return; 
    126         [server setObjectValue:[[notification userInfo] objectForKey:@"server"]]; 
    127 
    128  
    129 - (void) gotUserChannels:(NSNotification *) notification { 
    130         if( [[[notification userInfo] objectForKey:@"who"] caseInsensitiveCompare:[_member nickname]] != NSOrderedSame ) return; 
    131         [rooms setObjectValue:[[[notification userInfo] objectForKey:@"channels"] componentsJoinedByString:@" "]]; 
    132 
    133  
    134 - (void) gotUserOperator:(NSNotification *) notification { 
    135         if( [[[notification userInfo] objectForKey:@"who"] caseInsensitiveCompare:[_member nickname]] != NSOrderedSame ) return; 
    136         _classSet = YES; 
    137         [class setObjectValue:NSLocalizedString( @"Server operator", "server operator class" )]; 
    138 
    139  
    140 - (void) gotUserIdle:(NSNotification *) notification { 
    141         if( [[[notification userInfo] objectForKey:@"who"] caseInsensitiveCompare:[_member nickname]] != NSOrderedSame ) return; 
    142         [connected setObjectValue:MVReadableTime( [[[notification userInfo] objectForKey:@"connected"] doubleValue], YES )]; 
    143         [idle setObjectValue:MVReadableTime( [[NSDate date] timeIntervalSince1970] + [[[notification userInfo] objectForKey:@"idle"] doubleValue], YES )]; 
    144 
    145  
    146 - (void) gotUserWhoisComplete:(NSNotification *) notification { 
    147         if( [[[notification userInfo] objectForKey:@"who"] caseInsensitiveCompare:[_member nickname]] != NSOrderedSame ) return; 
    148         _whoisComplete = YES; 
    149         if (!_classSet) 
    150                 [class setObjectValue:NSLocalizedString( @"Normal user", "normal user class" )]; 
    151         if (_addressResolved) 
    152                 [progress stopAnimation:nil]; 
    153 
    154  
    155 - (void) gotAwayStatus:(NSNotification *) notification { 
    156         if( [[[notification userInfo] objectForKey:@"who"] caseInsensitiveCompare:[_member nickname]] != NSOrderedSame ) return; 
    157         NSData *data = [[notification userInfo] objectForKey:@"message"]; 
    158         NSString *strMsg = [[[NSString alloc] initWithData:data encoding:[[_member connection] encoding]] autorelease]; 
    159         if( ! strMsg ) strMsg = [NSString stringWithCString:[data bytes] length:[data length]]; 
    160         [away setObjectValue:strMsg]; 
    161 
    162  
    163 - (void) errorOccurred:(NSNotification *) notification { 
    164 /*      MVChatError error = (MVChatError) [[[notification userInfo] objectForKey:@"error"] intValue]; 
    165         id target = [[notification userInfo] objectForKey:@"target"]; 
    166         if( ! [target isKindOfClass:[NSString class]] || [target caseInsensitiveCompare:[_member nickname]] != NSOrderedSame ) return; 
    167         if( error == MVChatBadTargetError ) { 
    168                 [progress stopAnimation:nil]; 
    169                 [address setObjectValue:NSLocalizedString( @"n/a", "not applicable or not available" )]; 
    170                 [address setToolTip:nil]; 
    171         } */ 
    172 
    173  
    174 - (void) gotCTCPResponse:(NSNotification *) notification { 
    175         if( [[[notification userInfo] objectForKey:@"from"] caseInsensitiveCompare:[_member nickname]] != NSOrderedSame ) return; 
    176         if( [[[notification userInfo] objectForKey:@"command"] caseInsensitiveCompare:@"VERSION"] == NSOrderedSame ) { 
    177                 [clientInfo setStringValue:[[notification userInfo] objectForKey:@"arguments"]]; 
     130- (void) attributeUpdated:(NSNotification *) notification { 
     131        NSString *key = [[notification userInfo] objectForKey:@"attribute"]; 
     132        if( [key isEqualToString:MVChatUserLocalTimeDifferenceAttribute] ) { 
     133                if( ! _localTimeUpdateTimer ) 
     134                        _localTimeUpdateTimer = [[NSTimer scheduledTimerWithTimeInterval:10. target:self selector:@selector( updateLocalTime ) userInfo:nil repeats:YES] retain]; 
     135        } else if( [key isEqualToString:MVChatUserClientInfoAttribute] ) { 
     136                [clientInfo setObjectValue:[[_member user] attributeForKey:key]]; 
     137                [clientInfo setToolTip:[[_member user] attributeForKey:key]]; 
    178138        } 
    179139} 
    180140 
     141- (void) updateLocalTime { 
     142        NSString *format = [[NSUserDefaults standardUserDefaults] objectForKey:NSShortTimeDateFormatString]; 
     143        NSDate *current = [[NSDate dateWithTimeIntervalSinceNow:[[[_member user] attributeForKey:MVChatUserLocalTimeDifferenceAttribute] doubleValue]] dateWithCalendarFormat:format timeZone:nil]; 
     144        [localTime setObjectValue:current]; 
     145} 
     146 
    181147- (IBAction) sendPing:(id) sender { 
    182 //      [[_member connection] sendSubcodeRequest:@"PING" toUser:[_member nickname] withArguments:nil]; 
     148 
    183149} 
    184150 
    185151- (IBAction) requestLocalTime:(id) sender { 
    186 //     [[_member connection] sendSubcodeRequest:@"TIME" toUser:[_member nickname] withArguments:nil]; 
     152       [[_member user] refreshAttributeForKey:MVChatUserLocalTimeDifferenceAttribute]; 
    187153} 
    188154 
    189155- (IBAction) requestClientInfo:(id) sender { 
    190 //     [[_member connection] sendSubcodeRequest:@"VERSION" toUser:[_member nickname] withArguments:nil]; 
     156       [[_member user] refreshAttributeForKey:MVChatUserClientInfoAttribute]; 
    191157} 
    192158@end 
  • trunk/JVChatRoom.m

    r2212 r2224  
    6262                [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _memberParted: ) name:MVChatRoomUserPartedNotification object:target]; 
    6363                [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _memberKicked: ) name:MVChatRoomUserKickedNotification object:target]; 
    64                 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _roomModeChanged: ) name:MVChatRoomModeChangedNotification object:target]; 
     64                [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _roomModeChanged: ) name:MVChatRoomModesChangedNotification object:target]; 
    6565                [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _memberModeChanged: ) name:MVChatRoomUserModeChangedNotification object:target]; 
    6666                [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _memberBanned: ) name:MVChatRoomUserBannedNotification object:target]; 
  • trunk/JVChatRoomInspector.h

    r1823 r2224  
    2525        JVChatRoom *_room; 
    2626        BOOL _nibLoaded; 
    27         unsigned int _modes; 
    28         NSString *_key; 
    29         int _limit; 
    3027} 
    3128- (id) initWithRoom:(JVChatRoom *) room; 
  • trunk/JVChatRoomInspector.m

    r2193 r2224  
    55#import <ChatCore/MVChatConnection.h> 
    66#import <ChatCore/MVChatRoom.h> 
     7#import <ChatCore/NSAttributedStringAdditions.h> 
    78 
    89@interface JVChatTranscript (JVChatTranscriptPrivate) 
     
    2930@implementation JVChatRoom (JVChatRoomInspection) 
    3031- (id <JVInspector>) inspector { 
    31         return nil; //[[[JVChatRoomInspector alloc] initWithRoom:self] autorelease]; 
     32        return [[[JVChatRoomInspector alloc] initWithRoom:self] autorelease]; 
    3233} 
    3334@end 
     
    3738@implementation JVChatRoomInspector 
    3839- (id) initWithRoom:(JVChatRoom *) room { 
    39         if( ( self = [self init] ) ) { 
     40        if( ( self = [self init] ) ) 
    4041                _room = [room retain]; 
    41                 _modes = 0; 
    42                 _key = [[NSString alloc] init]; 
    43                 _limit = 0; 
    44         } 
    4542        return self; 
    4643} 
     
    7572 
    7673- (void) willLoad { 
    77         [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@", [_room target]]]; 
    78  
    79 //      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _topicChanged: ) name:MVChatConnectionGotRoomTopicNotification object:[_room connection]]; 
    80 //      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _refreshEditStatus: ) name:MVChatConnectionGotMemberModeNotification object:[_room connection]]; 
    81         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _roomModeChanged: ) name:MVChatRoomModeChangedNotification object:_room]; 
     74        [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@", (MVChatRoom *)[_room target]]]; 
     75 
     76        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _topicChanged: ) name:MVChatRoomTopicChangedNotification object:[_room target]]; 
     77        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _refreshEditStatus: ) name:MVChatRoomUserModeChangedNotification object:[_room target]]; 
     78        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _roomModeChanged: ) name:MVChatRoomModesChangedNotification object:[_room target]]; 
     79        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _refreshEditStatus: ) name:MVChatRoomKickedNotification object:[_room target]]; 
    8280 
    8381        [encodingSelection setMenu:[_room _encodingMenu]]; 
     
    9593                [password setEnabled:(BOOL)[sender state]]; 
    9694                if( [sender state] ) [[password window] makeFirstResponder:password]; 
    97                 else [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@ -k *", [_room target]]]; 
     95                else [(MVChatRoom *)[_room target] removeMode:MVChatRoomPassphraseToJoinMode]; 
    9896        } else if( sender == limitMembers ) { 
    9997                [memberLimit setEnabled:(BOOL)[sender state]]; 
    10098                if( [sender state] ) [[memberLimit window] makeFirstResponder:memberLimit]; 
    101                 else [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@ -l *", [_room target]]]; 
     99                else [(MVChatRoom *)[_room target] removeMode:MVChatRoomLimitNumberOfMembersMode]; 
    102100        } else if( sender == password ) { 
    103101                BOOL enabled = ( [[sender stringValue] length] ? YES : NO ); 
    104                 if( enabled ) [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@ +k %@", [_room target], [sender stringValue]]]; 
     102                if( enabled ) [(MVChatRoom *)[_room target] setMode:MVChatRoomPassphraseToJoinMode withAttribute:[sender stringValue]]; 
    105103                else { 
    106104                        [requiresPassword setState:NSOffState]; 
     
    109107        } else if( sender == memberLimit ) { 
    110108                BOOL enabled = ( [sender intValue] > 1 ? YES : NO ); 
    111                 if( enabled ) [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@ +l %d", [_room target], [sender intValue]]]; 
     109                if( enabled ) [(MVChatRoom *)[_room target] setMode:MVChatRoomLimitNumberOfMembersMode withAttribute:[sender stringValue]]; 
    112110                else { 
    113111                        [limitMembers setState:NSOffState]; 
     
    115113                } 
    116114        } else if( [sender selectedCell] == privateRoom ) { 
    117                 [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@ %cp", [_room target], ( [[sender selectedCell] state] ? '+' : '-' )]]; 
     115                if( [[sender selectedCell] state] ) [(MVChatRoom *)[_room target] setMode:MVChatRoomPrivateMode]; 
     116                else [(MVChatRoom *)[_room target] removeMode:MVChatRoomPrivateMode]; 
    118117        } else if( [sender selectedCell] == secretRoom ) { 
    119                 [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@ %cs", [_room target], ( [[sender selectedCell] state] ? '+' : '-' )]]; 
     118                if( [[sender selectedCell] state] ) [(MVChatRoom *)[_room target] setMode:MVChatRoomSecretMode]; 
     119                else [(MVChatRoom *)[_room target] removeMode:MVChatRoomSecretMode]; 
    120120        } else if( [sender selectedCell] == inviteOnly ) { 
    121                 [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@ %ci", [_room target], ( [[sender selectedCell] state] ? '+' : '-' )]]; 
     121                if( [[sender selectedCell] state] ) [(MVChatRoom *)[_room target] setMode:MVChatRoomInviteOnlyMode]; 
     122                else [(MVChatRoom *)[_room target] removeMode:MVChatRoomInviteOnlyMode]; 
    122123        } else if( [sender selectedCell] == noOutside ) { 
    123                 [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@ %cn", [_room target], ( [[sender selectedCell] state] ? '+' : '-' )]]; 
     124                if( [[sender selectedCell] state] ) [(MVChatRoom *)[_room target] setMode:MVChatRoomNoOutsideMessagesMode]; 
     125                else [(MVChatRoom *)[_room target] removeMode:MVChatRoomNoOutsideMessagesMode]; 
    124126        } else if( [sender selectedCell] == topicChangeable ) { 
    125                 [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@ %ct", [_room target], ( [[sender selectedCell] state] ? '+' : '-' )]]; 
     127                if( [[sender selectedCell] state] ) [(MVChatRoom *)[_room target] setMode:MVChatRoomOperatorsOnlySetTopicMode]; 
     128                else [(MVChatRoom *)[_room target] removeMode:MVChatRoomOperatorsOnlySetTopicMode]; 
    126129        } else if( [sender selectedCell] == moderated ) { 
    127                 [[_room connection] sendRawMessage:[NSString stringWithFormat:@"MODE %@ %cm", [_room target], ( [[sender selectedCell] state] ? '+' : '-' )]]; 
     130                if( [[sender selectedCell] state] ) [(MVChatRoom *)[_room target] setMode:MVChatRoomNormalUsersSilencedMode]; 
     131                else [(MVChatRoom *)[_room target] removeMode:MVChatRoomNormalUsersSilencedMode]; 
    128132        } 
    129133} 
     
    136140 
    137141- (BOOL) textView:(NSTextView *) textView returnKeyPressed:(NSEvent *) event { 
    138 /*    unichar zeroWidthSpaceChar = 0x200b;     
     142      unichar zeroWidthSpaceChar = 0x200b;     
    139143        [[[topic textStorage] mutableString] replaceOccurrencesOfString:[NSString stringWithCharacters:&zeroWidthSpaceChar length:1] withString:@"" options:NSLiteralSearch range:NSMakeRange( 0, [[topic textStorage] length] )]; 
    140         [[_room connection] setTopic:[topic textStorage] withEncoding:[_room encoding] forRoom:[_room target]]; */ 
     144        [(MVChatRoom *)[_room target] setTopic:[topic textStorage]]; 
    141145        return YES; 
    142146} 
     
    148152 
    149153- (void) textDidEndEditing:(NSNotification *) notification { 
    150 //     [[_room connection] setTopic:[topic textStorage] withEncoding:[_room encoding] forRoom:[_room target]]; 
     154       [self textView:topic returnKeyPressed:nil]; 
    151155} 
    152156@end 
     
    156160@implementation JVChatRoomInspector (JVChatRoomInspectorPrivate) 
    157161- (void) _topicChanged:(NSNotification *) notification { 
    158         if( [[[notification userInfo] objectForKey:@"room"] caseInsensitiveCompare:[_room target]] != NSOrderedSame ) return; 
    159162        if( [[topic window] firstResponder] == topic && [topic isEditable] ) return; 
    160163 
    161         NSMutableAttributedString *topicString = [[[[_room target] topic] mutableCopy] autorelease]; 
    162         [topicString removeAttribute:NSParagraphStyleAttributeName range:NSMakeRange( 0, [topicString length] )]; 
    163         [topicString removeAttribute:NSLinkAttributeName range:NSMakeRange( 0, [topicString length] )]; 
    164         [[topic textStorage] setAttributedString:topicString]; 
     164        NSFont *baseFont = [NSFont userFontOfSize:12.]; 
     165        NSMutableDictionary *options = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:[_room encoding]], @"StringEncoding", [NSNumber numberWithBool:[[NSUserDefaults standardUserDefaults] boolForKey:@"JVChatStripMessageColors"]], @"IgnoreFontColors", [NSNumber numberWithBool:[[NSUserDefaults standardUserDefaults] boolForKey:@"JVChatStripMessageFormatting"]], @"IgnoreFontTraits", baseFont, @"BaseFont", nil]; 
     166        NSAttributedString *messageString = [NSMutableAttributedString attributedStringWithIRCFormat:[(MVChatRoom *)[_room target] topic] options:options]; 
     167 
     168        if( ! messageString ) { 
     169                [options setObject:[NSNumber numberWithUnsignedInt:[NSString defaultCStringEncoding]] forKey:@"StringEncoding"]; 
     170                messageString = [NSAttributedString attributedStringWithIRCFormat:[(MVChatRoom *)[_room target] topic] options:options]; 
     171        } 
     172 
     173        [[topic textStorage] setAttributedString:messageString]; 
    165174} 
    166175 
    167176- (void) _refreshEditStatus:(NSNotification *) notification { 
    168         if( notification && [[[notification userInfo] objectForKey:@"room"] caseInsensitiveCompare:[_room target]] != NSOrderedSame && [[[_room connection] nickname] isEqualToString:[[notification userInfo] objectForKey:@"who"]] ) return; 
    169  
    170         BOOL canEdit = NO; // [[_room chatRoomMemberWithName:[[_room connection] nickname]] operator]
     177        if( notification && ! [[[notification userInfo] objectForKey:@"who"] isLocalUser] ) return; 
     178 
     179        BOOL canEdit = [(MVChatRoom *)[_room target] modesForMemberUser:[[_room connection] localUser]] & MVChatRoomMemberOperatorMode
    171180 
    172181        [topicChangeable setEnabled:canEdit]; 
     
    176185        [noOutside setEnabled:canEdit]; 
    177186        [moderated setEnabled:canEdit]; 
    178          
    179 //     [topic setEditable:(canEdit || ! (_modes & MVChatRoomSetTopicOperatorOnlyMode))]; 
     187 
     188       [topic setEditable:( canEdit || ! ( [(MVChatRoom *)[_room target] modes] & MVChatRoomOperatorsOnlySetTopicMode ) )]; 
    180189 
    181190        [limitMembers setEnabled:canEdit]; 
     
    189198 
    190199- (void) _roomModeChanged:(NSNotification *) notification { 
    191         //if( [notification object] != _room ) return; 
    192          
    193 /*      unsigned int currentModes = [_room modes]; 
    194         unsigned int newModes = currentModes & ~ _modes; 
    195         unsigned int oldModes = _modes & ~ currentModes; 
    196         unsigned int changedModes = newModes | oldModes; 
    197         _modes = [_room modes]; 
    198         NSString *key = [_room key]; 
    199         int limit = [_room limit]; 
    200                          
    201         if (changedModes & MVChatRoomPrivateMode) { 
    202                 [privateRoom setState:(newModes & MVChatRoomPrivateMode ? NSOnState : NSOffState)]; 
    203         } 
    204         if (changedModes & MVChatRoomSecretMode) { 
    205                 [secretRoom setState:(newModes & MVChatRoomSecretMode ? NSOnState : NSOffState)]; 
    206         } 
    207         if (changedModes & MVChatRoomInviteOnlyMode) { 
    208                 [inviteOnly setState:(newModes & MVChatRoomInviteOnlyMode ? NSOnState : NSOffState)]; 
    209         } 
    210         if (changedModes & MVChatRoomModeratedMode) { 
    211                 [moderated setState:(newModes & MVChatRoomModeratedMode ? NSOnState : NSOffState)]; 
    212         } 
    213         if (changedModes & MVChatRoomSetTopicOperatorOnlyMode) { 
    214                 BOOL enabled = (newModes & MVChatRoomSetTopicOperatorOnlyMode ? YES : NO); 
    215                 if (enabled) [self _topicChanged:nil]; 
    216                 if ([[_room chatRoomMemberWithName:[[_room connection] nickname]] operator]) { 
    217                         [topic setEditable:YES]; 
    218                 } else [topic setEditable: (!enabled)]; 
    219                 [topicChangeable setState:(enabled ? NSOnState : NSOffState)]; 
    220         } 
    221         if (changedModes & MVChatRoomNoOutsideMessagesMode) { 
    222                 [noOutside setState:(newModes & MVChatRoomNoOutsideMessagesMode ? NSOnState : NSOffState)]; 
    223         } 
    224         if ((changedModes & MVChatRoomPasswordRequiredMode) ||  
    225                 ((currentModes & MVChatRoomPasswordRequiredMode) && ![key isEqualToString:_key])) { 
    226                 [requiresPassword setState:(newModes & MVChatRoomPasswordRequiredMode ? NSOnState : NSOffState)]; 
    227                 if (currentModes & MVChatRoomPasswordRequiredMode) { 
    228                         [password setStringValue:key]; 
    229                         [_key autorelease]; 
    230                         _key = [key copy]; 
    231                 } else { 
    232                         [password setStringValue:@""]; 
    233                 } 
    234         } 
    235         if ((changedModes & MVChatRoomMemberLimitMode) || 
    236                 ((currentModes & MVChatRoomMemberLimitMode) && (limit != _limit))) { 
    237                 [limitMembers setState:(newModes & MVChatRoomMemberLimitMode ? NSOnState : NSOffState)]; 
    238                 if (currentModes & MVChatRoomMemberLimitMode) { 
    239                         [memberLimit setIntValue:limit]; 
    240                         _limit = limit; 
    241                 } else { 
    242                         [memberLimit setStringValue:@""]; 
    243                 } 
    244         } 
    245          
    246         [self _refreshEditStatus:nil]; */ 
    247 
    248 @end 
     200        unsigned int changedModes = ( notification ? [[[notification userInfo] objectForKey:@"changedModes"] unsignedIntValue] : [(MVChatRoom *)[_room target] modes] ); 
     201        unsigned int newModes = [(MVChatRoom *)[_room target] modes]; 
     202 
     203        if( changedModes & MVChatRoomPrivateMode ) 
     204                [privateRoom setState:( newModes & MVChatRoomPrivateMode ? NSOnState : NSOffState )]; 
     205 
     206        if( changedModes & MVChatRoomSecretMode ) 
     207                [secretRoom setState:( newModes & MVChatRoomSecretMode ? NSOnState : NSOffState )]; 
     208 
     209        if( changedModes & MVChatRoomInviteOnlyMode ) 
     210                [inviteOnly setState:( newModes & MVChatRoomInviteOnlyMode ? NSOnState : NSOffState )]; 
     211 
     212        if( changedModes & MVChatRoomNormalUsersSilencedMode ) 
     213                [moderated setState:( newModes & MVChatRoomNormalUsersSilencedMode ? NSOnState : NSOffState )]; 
     214 
     215        if( changedModes & MVChatRoomOperatorsOnlySetTopicMode ) { 
     216                BOOL enabled = ( newModes & MVChatRoomOperatorsOnlySetTopicMode ? YES : NO ); 
     217                if( enabled ) [self _topicChanged:nil]; 
     218                if( [(MVChatRoom *)[_room target] modesForMemberUser:[[_room connection] localUser]] & MVChatRoomMemberOperatorMode ) [topic setEditable:YES]; 
     219                else [topic setEditable:( ! enabled )]; 
     220                [topicChangeable setState:( enabled ? NSOnState : NSOffState )]; 
     221        } 
     222 
     223        if( changedModes & MVChatRoomNoOutsideMessagesMode ) 
     224                [noOutside setState:( newModes & MVChatRoomNoOutsideMessagesMode ? NSOnState : NSOffState )]; 
     225 
     226        if( changedModes & MVChatRoomPassphraseToJoinMode ) { 
     227                [requiresPassword setState:( newModes & MVChatRoomPassphraseToJoinMode ? NSOnState : NSOffState )]; 
     228                if( newModes & MVChatRoomPassphraseToJoinMode ) [password setStringValue:[(MVChatRoom *)[_room target] attributeForMode:MVChatRoomPassphraseToJoinMode]]; 
     229                else [password setStringValue:@""]; 
     230        } 
     231 
     232        if( changedModes & MVChatRoomLimitNumberOfMembersMode ) { 
     233                [limitMembers setState:( newModes & MVChatRoomLimitNumberOfMembersMode ? NSOnState : NSOffState )]; 
     234                if( newModes & MVChatRoomLimitNumberOfMembersMode ) [memberLimit setObjectValue:[(MVChatRoom *)[_room target] attributeForMode:MVChatRoomLimitNumberOfMembersMode]]; 
     235                else [memberLimit setStringValue:@""]; 
     236        } 
     237 
     238        [self _refreshEditStatus:nil]; 
     239
     240@end 
  • trunk/MVChatRoom.h

    r2207 r2224  
    3838extern NSString *MVChatRoomGotMessageNotification; 
    3939extern NSString *MVChatRoomTopicChangedNotification; 
    40 extern NSString *MVChatRoomModeChangedNotification; 
    41 extern NSString *MVChatRoomAttributesUpdatedNotification; 
     40extern NSString *MVChatRoomModesChangedNotification; 
     41extern NSString *MVChatRoomAttributeUpdatedNotification; 
    4242 
    4343@class MVChatConnection; 
  • trunk/MVChatRoom.m

    r2214 r2224  
    44 
    55#import "NSStringAdditions.h" 
     6#import "NSNotificationAdditions.h" 
    67 
    78NSString *MVChatRoomJoinedNotification = @"MVChatRoomJoinedNotification"; 
     
    2223NSString *MVChatRoomGotMessageNotification = @"MVChatRoomGotMessageNotification"; 
    2324NSString *MVChatRoomTopicChangedNotification = @"MVChatRoomTopicChangedNotification"; 
    24 NSString *MVChatRoomModeChangedNotification = @"MVChatRoomModeChangedNotification"; 
    25 NSString *MVChatRoomAttributesUpdatedNotification = @"MVChatRoomAttributesUpdatedNotification"; 
     25NSString *MVChatRoomModesChangedNotification = @"MVChatRoomModesChangedNotification"; 
     26NSString *MVChatRoomAttributeUpdatedNotification = @"MVChatRoomAttributeUpdatedNotification"; 
    2627 
    2728@implementation MVChatRoom 
     
    555556        [_topicAuthor autorelease]; 
    556557        _topicAuthor = [author retain]; 
    557  
     558         
    558559        [_dateTopicChanged autorelease]; 
    559560        _dateTopicChanged = [date copyWithZone:[self zone]]; 
     561 
     562        NSNotification *note = [NSNotification notificationWithName:MVChatRoomTopicChangedNotification object:self userInfo:nil]; 
     563        [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; 
    560564} 
    561565 
     
    566570                else [_attributes removeObjectForKey:key]; 
    567571        } 
     572 
     573        NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:key, @"attribute", nil]; 
     574        NSNotification *note = [NSNotification notificationWithName:MVChatRoomAttributeUpdatedNotification object:self userInfo:info];           
     575        [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; 
    568576} 
    569577@end 
  • trunk/MVChatUser.h

    r2214 r2224  
    1919extern NSString *MVChatUserKnownRoomsAttribute; 
    2020extern NSString *MVChatUserPictureAttribute; 
    21 extern NSString *MVChatUserLocalTimeAttribute; 
     21extern NSString *MVChatUserLocalTimeDifferenceAttribute; 
    2222extern NSString *MVChatUserClientInfoAttribute; 
    2323extern NSString *MVChatUserVCardAttribute; 
     
    4343extern NSString *MVChatUserInformationUpdatedNotification; 
    4444extern NSString *MVChatUserAttributeUpdatedNotification; 
    45 extern NSString *MVChatUserAttributesUpdatedNotification; 
    4645 
    4746@class MVChatConnection; 
     
    118117- (unsigned long) modes; 
    119118 
     119- (void) refreshInformation; 
     120 
    120121- (void) refreshAttributes; 
    121122- (void) refreshAttributeForKey:(NSString *) key; 
  • trunk/MVChatUser.m

    r2214 r2224  
    22#import "MVChatConnection.h" 
    33#import "MVFileTransfer.h" 
     4#import "NSNotificationAdditions.h" 
    45 
    56NSString *MVChatUserKnownRoomsAttribute = @"MVChatUserKnownRoomsAttribute"; 
    67NSString *MVChatUserPictureAttribute = @"MVChatUserPictureAttribute"; 
    7 NSString *MVChatUserLocalTimeAttribute = @"MVChatUserLocalTimeAttribute"; 
     8NSString *MVChatUserLocalTimeDifferenceAttribute = @"MVChatUserLocalTimeDifferenceAttribute"; 
    89NSString *MVChatUserClientInfoAttribute = @"MVChatUserClientInfoAttribute"; 
    910NSString *MVChatUserVCardAttribute = @"MVChatUserVCardAttribute"; 
     
    2930NSString *MVChatUserInformationUpdatedNotification = @"MVChatUserInformationUpdatedNotification"; 
    3031NSString *MVChatUserAttributeUpdatedNotification = @"MVChatUserAttributeUpdatedNotification"; 
    31 NSString *MVChatUserAttributesUpdatedNotification = @"MVChatUserAttributesUpdatedNotification"; 
    3232 
    3333@implementation MVChatUser 
     
    309309#pragma mark - 
    310310 
     311- (void) refreshInformation { 
     312// subclass this method, if needed       
     313} 
     314 
     315#pragma mark - 
     316 
    311317- (void) refreshAttributes { 
    312 // subclass this method, if needed       
     318        NSEnumerator *enumerator = [[self supportedAttributes] objectEnumerator]; 
     319        NSString *attribute = nil; 
     320        while( ( attribute = [enumerator nextObject] ) ) 
     321                [self refreshAttributeForKey:attribute]; 
    313322} 
    314323 
     
    430439- (void) _setIdleTime:(NSTimeInterval) time { 
    431440        _idleTime = time; 
     441 
     442        NSNotification *note = [NSNotification notificationWithName:MVChatUserIdleTimeUpdatedNotification object:self userInfo:nil];             
     443        [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; 
    432444} 
    433445 
     
    453465                else [_attributes removeObjectForKey:key]; 
    454466        } 
     467 
     468        NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:key, @"attribute", nil]; 
     469        NSNotification *note = [NSNotification notificationWithName:MVChatUserAttributeUpdatedNotification object:self userInfo:info];           
     470        [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; 
    455471} 
    456472@end 
  • trunk/MVIRCChatConnection.m

    r2223 r2224  
    348348 
    349349        NSData *msgData = [NSData dataWithBytes:channel -> topic length:strlen( channel -> topic )]; 
     350 
    350351        NSString *author = ( channel -> topic_by ? [self stringWithEncodedBytes:channel -> topic_by] : nil ); 
     352        NSArray *parts = [author componentsSeparatedByString:@"!"]; 
     353        author = ( [parts count] >= 1 ? [parts objectAtIndex:0] : nil ); 
     354 
    351355        MVChatUser *authorUser = ( author ? [self chatUserWithUniqueIdentifier:author] : nil ); 
    352356        NSDate *time = ( channel -> topic_time ? [NSDate dateWithTimeIntervalSince1970:channel -> topic_time] : nil ); 
     
    354358        MVChatRoom *room = [self joinedChatRoomWithName:[self stringWithEncodedBytes:channel -> name]]; 
    355359        [room _setTopic:msgData byAuthor:authorUser withDate:time]; 
    356  
    357         NSNotification *note = [NSNotification notificationWithName:MVChatRoomTopicChangedNotification object:room userInfo:nil]; 
    358         [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; 
    359360} 
    360361 
     
    705706        unsigned int changedModes = ( oldModes ^ [room modes] ); 
    706707 
    707         NSNotification *note = [NSNotification notificationWithName:MVChatRoomModeChangedNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:changedModes], @"changedModes", byMember, @"by", nil]]; 
     708        NSNotification *note = [NSNotification notificationWithName:MVChatRoomModesChangedNotification object:room userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:changedModes], @"changedModes", byMember, @"by", nil]]; 
    708709        [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; 
    709710} 
     
    903904                [user _setDateConnected:[NSDate dateWithTimeIntervalSince1970:[[self stringWithEncodedBytes:connected] intValue]]]; 
    904905        else [user _setDateConnected:nil]; 
    905  
    906         NSNotification *note = [NSNotification notificationWithName:MVChatUserIdleTimeUpdatedNotification object:user userInfo:nil];             
    907         [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:note]; 
    908906 
    909907        g_free( params ); 
  • trunk/MVIRCChatUser.m

    r2220 r2224  
    4242 
    4343- (NSSet *) supportedAttributes { 
    44         return [NSSet setWithObjects:MVChatUserKnownRoomsAttribute, MVChatUserLocalTimeAttribute, MVChatUserClientInfoAttribute, nil]; 
     44        return [NSSet setWithObjects:MVChatUserKnownRoomsAttribute, MVChatUserLocalTimeDifferenceAttribute, MVChatUserClientInfoAttribute, nil]; 
    4545} 
    4646 
     
    7474#pragma mark - 
    7575 
    76 - (void) refreshAttributes
     76- (void) refreshInformation
    7777        [[self connection] sendRawMessageWithFormat:@"WHOIS %@ %@", [self nickname], [self nickname]]; 
    7878} 
     
    8080- (void) refreshAttributeForKey:(NSString *) key { 
    8181        [super refreshAttributeForKey:key]; 
    82         if( [key isEqualToString:MVChatUserLocalTimeAttribute] ) { 
     82        if( [key isEqualToString:MVChatUserLocalTimeDifferenceAttribute] ) { 
    8383                [self sendSubcodeRequest:@"TIME" withArguments:nil]; 
    8484        } else if( [key isEqualToString:MVChatUserClientInfoAttribute] ) { 
     
    9595                [self _setAttribute:arguments forKey:MVChatUserClientInfoAttribute]; 
    9696        } else if( ! [command caseInsensitiveCompare:@"time"] ) { 
    97                 [self _setAttribute:[NSDate dateWithNaturalLanguageString:arguments] forKey:MVChatUserLocalTimeAttribute]; 
     97                NSDate *localThere = [NSDate dateWithNaturalLanguageString:arguments]; 
     98                if( localThere ) { 
     99                        NSTimeInterval diff = [localThere timeIntervalSinceDate:[NSDate date]]; 
     100                        [self _setAttribute:[NSNumber numberWithDouble:diff] forKey:MVChatUserLocalTimeDifferenceAttribute]; 
     101                } else [self _setAttribute:nil forKey:MVChatUserLocalTimeDifferenceAttribute];  
    98102        } 
    99103} 
  • trunk/MVSILCChatUser.m

    r2214 r2224  
    8080 
    8181- (NSSet *) supportedAttributes { 
    82         return [NSSet setWithObjects:MVChatUserKnownRoomsAttribute, MVChatUserPictureAttribute, MVChatUserLocalTimeAttribute, MVChatUserClientInfoAttribute, MVChatUserVCardAttribute, MVChatUserServiceAttribute, MVChatUserMoodAttribute, MVChatUserStatusMessageAttribute, MVChatUserPreferredLanguageAttribute, MVChatUserPreferredContactMethodsAttribute, MVChatUserTimezoneAttribute, MVChatUserGeoLocationAttribute, MVChatUserDeviceInfoAttribute, MVChatUserExtensionAttribute, MVChatUserPublicKeyAttribute, MVChatUserServerPublicKeyAttribute, MVChatUserDigitalSignatureAttribute, MVChatUserServerDigitalSignatureAttribute, nil]; 
     82        return [NSSet setWithObjects:MVChatUserKnownRoomsAttribute, MVChatUserPictureAttribute, MVChatUserLocalTimeDifferenceAttribute, MVChatUserClientInfoAttribute, MVChatUserVCardAttribute, MVChatUserServiceAttribute, MVChatUserMoodAttribute, MVChatUserStatusMessageAttribute, MVChatUserPreferredLanguageAttribute, MVChatUserPreferredContactMethodsAttribute, MVChatUserTimezoneAttribute, MVChatUserGeoLocationAttribute, MVChatUserDeviceInfoAttribute, MVChatUserExtensionAttribute, MVChatUserPublicKeyAttribute, MVChatUserServerPublicKeyAttribute, MVChatUserDigitalSignatureAttribute, MVChatUserServerDigitalSignatureAttribute, nil]; 
    8383} 
    8484 
     
    103103        } 
    104104} 
     105 
     106#pragma mark - 
     107 
     108- (void) refreshInformation { 
     109        [[self connection] sendRawMessageWithFormat:@"WHOIS %@", [self nickname]]; 
     110} 
    105111@end