Changeset 3484

Show
Ignore:
Timestamp:
12/24/06 23:39:31 (2 years ago)
Author:
timothy
Message:

Fixes to the buddy list code. This gets things working but the user interface still needed modified to work with the new code.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Chat Core/MVChatConnection.m

    r3457 r3484  
    921921        if( [user _onlineNotificationSent] ) return; 
    922922        if( [user isWatched] || [self _watchRulesMatchingUser:user] ) { 
    923                 [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionWatchedUserOnlineNotification object:user userInfo:nil]; 
    924923                [user _setOnlineNotificationSent:YES]; 
    925924                [user _setDateDisconnected:nil]; 
     
    928927                if( ! [user dateDisconnected] ) 
    929928                        [user _setDateConnected:[NSDate date]]; 
     929 
     930                [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionWatchedUserOnlineNotification object:user userInfo:nil]; 
    930931        } 
    931932} 
     
    934935        if( ! [user _onlineNotificationSent] ) return; 
    935936        if( [user isWatched] ) { 
    936                 [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionWatchedUserOfflineNotification object:user userInfo:nil]; 
    937937                [user _setOnlineNotificationSent:NO]; 
    938938                [user _setWatched:NO]; 
     
    941941                        [user _setDateDisconnected:[NSDate date]]; 
    942942                [user _setStatus:MVChatUserOfflineStatus]; 
     943 
     944                [user retain]; // retain since removeMatchedUser might hold the last reference 
    943945 
    944946                @synchronized( _chatUserWatchRules ) { 
     
    948950                                [rule removeMatchedUser:user]; 
    949951                } 
     952 
     953                [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionWatchedUserOfflineNotification object:user userInfo:nil]; 
     954 
     955                [user release]; 
    950956        } 
    951957} 
  • trunk/Chat Core/MVChatUserWatchRule.m

    r3457 r3484  
    3737- (NSDictionary *) dictionaryRepresentation { 
    3838        NSMutableDictionary *dictionary = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:5]; 
    39         if( _username ) [dictionary setObject:_nickname forKey:@"username"]; 
     39        if( _username ) [dictionary setObject:_username forKey:@"username"]; 
    4040        if( _nickname ) [dictionary setObject:_nickname forKey:@"nickname"]; 
    41         if( _realName ) [dictionary setObject:_nickname forKey:@"realName"]; 
    42         if( _address ) [dictionary setObject:_nickname forKey:@"address"]; 
    43         if( _publicKey ) [dictionary setObject:_nickname forKey:@"publicKey"]; 
     41        if( _realName ) [dictionary setObject:_realName forKey:@"realName"]; 
     42        if( _address ) [dictionary setObject:_address forKey:@"address"]; 
     43        if( _publicKey ) [dictionary setObject:_publicKey forKey:@"publicKey"]; 
    4444        if( _interim ) [dictionary setObject:[NSNumber numberWithBool:_interim] forKey:@"interim"]; 
    4545        if( _applicableServerDomains ) [dictionary setObject:_applicableServerDomains forKey:@"applicableServerDomains"]; 
  • trunk/Controllers/MVBuddyListController.h

    r3072 r3484  
    5353+ (MVBuddyListController *) sharedBuddyList; 
    5454 
     55- (void) save; 
     56 
    5557- (IBAction) getInfo:(id) sender; 
    5658 
  • trunk/Controllers/MVBuddyListController.m

    r3460 r3484  
    1919 
    2020@interface MVBuddyListController (MVBuddyListControllerPrivate) 
    21 - (void) _saveBuddyList; 
    2221- (void) _loadBuddyList; 
    2322- (void) _sortBuddies; 
     
    7877 
    7978- (void) dealloc { 
    80         [self _saveBuddyList]; 
     79        [self save]; 
    8180 
    8281        [[NSNotificationCenter defaultCenter] removeObserver:self]; 
     
    129128        [buddies reloadData]; 
    130129        [self _setBuddiesNeedSortAnimated]; 
     130} 
     131 
     132#pragma mark - 
     133 
     134- (void) save { 
     135        NSMutableArray *list = [[NSMutableArray allocWithZone:nil] initWithCapacity:[_buddyList count]]; 
     136        NSEnumerator *enumerator = [_buddyList objectEnumerator]; 
     137        JVBuddy *buddy = nil; 
     138 
     139        while( ( buddy = [enumerator nextObject] ) ) { 
     140                NSDictionary *buddyRep = [buddy dictionaryRepresentation]; 
     141                if( buddyRep ) [list addObject:buddyRep]; 
     142        } 
     143 
     144        [list writeToFile:[@"~/Library/Application Support/Colloquy/Buddy List.plist" stringByExpandingTildeInPath] atomically:YES]; 
     145        [list release]; 
    131146} 
    132147 
     
    233248//              JVBuddy *buddy = [JVBuddy buddyWithPerson:person]; 
    234249//              [self _addBuddyToList:buddy]; 
    235                 [self _saveBuddyList]; 
     250                [self save]; 
    236251        } 
    237252} 
     
    338353//              JVBuddy *buddy = [JVBuddy buddyWithPerson:person]; 
    339354//              [self _addBuddyToList:buddy]; 
    340                 [self _saveBuddyList]; 
     355                [self save]; 
    341356        } 
    342357 
     
    583598        [buddy release]; 
    584599        [self _manuallySortAndUpdate]; 
    585         [self _saveBuddyList]; 
     600        [self save]; 
    586601} 
    587602 
     
    966981} 
    967982 
    968 - (void) _saveBuddyList { 
    969         NSMutableArray *list = [[NSMutableArray allocWithZone:nil] initWithCapacity:[_buddyList count]]; 
    970         NSEnumerator *enumerator = [_buddyList objectEnumerator]; 
    971         JVBuddy *buddy = nil; 
    972  
    973         while( ( buddy = [enumerator nextObject] ) ) 
    974                 [list addObject:[buddy dictionaryRepresentation]]; 
    975  
    976         [list writeToFile:[@"~/Library/Application Support/Colloquy/Buddy List.plist" stringByExpandingTildeInPath] atomically:YES]; 
    977         [list release]; 
    978 } 
    979  
    980983- (void) _loadBuddyList { 
    981984        NSArray *list = [[NSArray allocWithZone:nil] initWithContentsOfFile:[@"~/Library/Application Support/Colloquy/Buddy List.plist" stringByExpandingTildeInPath]]; 
     
    10291032        [buddy release]; 
    10301033        [self _manuallySortAndUpdate]; 
    1031         [self _saveBuddyList]; 
     1034        [self save]; 
    10321035} 
    10331036 
  • trunk/Inspectors/JVBuddyInspector.m

    r3418 r3484  
    11#import "MVConnectionsController.h" 
     2#import "MVBuddyListController.h" 
    23#import "JVBuddyInspector.h" 
    34 
     
    8384- (BOOL) shouldUnload { 
    8485        [[view window] makeFirstResponder:view]; 
     86        [[MVBuddyListController sharedBuddyList] save]; 
    8587        return YES; 
    8688} 
  • trunk/Models/JVBuddy.h

    r3418 r3484  
    1010 
    1111@class ABPerson; 
    12 @class MVChatUserWatchRule; 
    1312 
    1413extern NSString * const JVBuddyAddressBookIRCNicknameProperty; 
     
    2625        NSMutableArray *_users; 
    2726        MVChatUser *_activeUser; 
     27        NSImage *_picture; 
     28        NSString *_firstName; 
     29        NSString *_lastName; 
     30        NSString *_primaryEmail; 
     31        NSString *_givenNickname; 
     32        NSString *_speechVoice; 
     33        NSString *_uniqueIdentifier; 
    2834} 
    2935+ (JVBuddyName) preferredName; 
     
    3339- (NSDictionary *) dictionaryRepresentation; 
    3440 
     41- (void) registerWithConnection:(MVChatConnection *) connection; 
    3542- (void) registerWithApplicableConnections; 
     43- (void) unregisterWithConnection:(MVChatConnection *) connection; 
    3644- (void) unregisterWithApplicableConnections; 
    3745 
     
    6573- (NSString *) givenNickname; 
    6674- (NSString *) speechVoice; 
     75- (NSString *) uniqueIdentifier; 
    6776 
    6877- (void) setFirstName:(NSString *) name; 
     
    7180- (void) setGivenNickname:(NSString *) name; 
    7281- (void) setSpeechVoice:(NSString *) voice; 
    73 - (NSString *) uniqueIdentifier; 
    74 - (ABPerson *) person; 
    7582 
     83- (ABPerson *) addressBookPersonRecord; 
    7684- (void) editInAddressBook; 
    7785- (void) viewInAddressBook; 
  • trunk/Models/JVBuddy.m

    r3418 r3484  
    11#import "JVBuddy.h" 
    22#import "MVConnectionsController.h" 
     3 
     4#import <ChatCore/NSStringAdditions.h> 
    35 
    46NSString *JVBuddyCameOnlineNotification = @"JVBuddyCameOnlineNotification"; 
     
    3032- (id) initWithDictionaryRepresentation:(NSDictionary *) dictionary { 
    3133        if( ( self = [super init] ) ) { 
    32                 _rules = [[NSMutableArray allocWithZone:nil] initWithCapacity:10]; 
     34                _rules = [[NSMutableArray allocWithZone:nil] initWithCapacity:5]; 
    3335                _users = [[NSMutableArray allocWithZone:nil] initWithCapacity:5]; 
    34                 _activeUser = nil; 
     36 
     37                NSData *data = [dictionary objectForKey:@"picture"]; 
     38                if( [data isKindOfClass:[NSData class]] && [data length] ) 
     39                        _picture = [[NSKeyedUnarchiver unarchiveObjectWithData:data] retain]; 
     40 
     41                NSString *string = [dictionary objectForKey:@"firstName"]; 
     42                if( [string isKindOfClass:[NSString class]] ) 
     43                        _firstName = [string copyWithZone:nil]; 
     44 
     45                string = [dictionary objectForKey:@"lastName"]; 
     46                if( [string isKindOfClass:[NSString class]] ) 
     47                        _lastName = [string copyWithZone:nil]; 
     48 
     49                string = [dictionary objectForKey:@"primaryEmail"]; 
     50                if( [string isKindOfClass:[NSString class]] ) 
     51                        _primaryEmail = [string copyWithZone:nil]; 
     52 
     53                string = [dictionary objectForKey:@"givenNickname"]; 
     54                if( [string isKindOfClass:[NSString class]] ) 
     55                        _givenNickname = [string copyWithZone:nil]; 
     56 
     57                string = [dictionary objectForKey:@"speechVoice"]; 
     58                if( [string isKindOfClass:[NSString class]] ) 
     59                        _speechVoice = [string copyWithZone:nil]; 
     60 
     61                string = [dictionary objectForKey:@"uniqueIdentifier"]; 
     62                if( [string isKindOfClass:[NSString class]] ) 
     63                        _uniqueIdentifier = [string copyWithZone:nil]; 
     64                if( ! [_uniqueIdentifier length] ) 
     65                        _uniqueIdentifier = [[NSString locallyUniqueString] retain]; 
     66 
     67                string = [dictionary objectForKey:@"addressBookPersonRecord"]; 
     68                if( [string isKindOfClass:[NSString class]] ) 
     69                        _person = [[[ABAddressBook sharedAddressBook] recordForUniqueId:string] retain]; 
    3570 
    3671                NSEnumerator *enumerator = [[dictionary objectForKey:@"rules"] objectEnumerator]; 
    3772                NSDictionary *ruleDictionary = nil; 
    3873                while( ( ruleDictionary = [enumerator nextObject] ) ) { 
    39                         MVChatUserWatchRule *rule = [[MVChatUserWatchRule allocWithZone:[self zone]] initWithDictionaryRepresentation:ruleDictionary]; 
     74                        MVChatUserWatchRule *rule = [[MVChatUserWatchRule allocWithZone:nil] initWithDictionaryRepresentation:ruleDictionary]; 
    4075                        if( rule ) [self addWatchRule:rule]; 
    4176                        [rule release]; 
     
    6095        [_users release]; 
    6196        [_activeUser release]; 
     97        [_picture release]; 
     98        [_firstName release]; 
     99        [_lastName release]; 
     100        [_primaryEmail release]; 
     101        [_givenNickname release]; 
     102        [_speechVoice release]; 
     103        [_uniqueIdentifier release]; 
    62104 
    63105        _person = nil; 
     
    65107        _rules = nil; 
    66108        _activeUser = nil; 
     109        _picture = nil; 
     110        _firstName = nil; 
     111        _lastName = nil; 
     112        _primaryEmail = nil; 
     113        _givenNickname = nil; 
     114        _speechVoice = nil; 
     115        _uniqueIdentifier = nil; 
    67116 
    68117        [super dealloc]; 
     
    72121 
    73122- (NSDictionary *) dictionaryRepresentation { 
    74         NSMutableDictionary *dictionary = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:5]; 
    75         [dictionary setObject:_rules forKey:@"rules"]; 
    76         return dictionary; 
    77 
    78  
    79 #pragma mark - 
     123        NSMutableDictionary *dictionary = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:8]; 
     124 
     125        NSEnumerator *enumerator = [_rules objectEnumerator]; 
     126        NSMutableArray *rules = [[NSMutableArray allocWithZone:nil] initWithCapacity:[_rules count]]; 
     127        MVChatUserWatchRule *rule = nil; 
     128 
     129        while( ( rule = [enumerator nextObject] ) ) { 
     130                NSDictionary *dictRep = [rule dictionaryRepresentation]; 
     131                if( dictRep ) [rules addObject:dictRep]; 
     132        } 
     133 
     134        [dictionary setObject:rules forKey:@"rules"]; 
     135        [rules release]; 
     136 
     137        if( _picture ) { 
     138                NSData *imageData = [NSKeyedArchiver archivedDataWithRootObject:_picture]; 
     139                if( imageData ) [dictionary setObject:imageData forKey:@"picture"]; 
     140        } 
     141 
     142        if( _firstName ) 
     143                [dictionary setObject:_firstName forKey:@"firstName"]; 
     144 
     145        if( _lastName ) 
     146                [dictionary setObject:_lastName forKey:@"lastName"]; 
     147 
     148        if( _primaryEmail ) 
     149                [dictionary setObject:_primaryEmail forKey:@"primaryEmail"]; 
     150 
     151        if( _givenNickname ) 
     152                [dictionary setObject:_givenNickname forKey:@"givenNickname"]; 
     153 
     154        if( _speechVoice ) 
     155                [dictionary setObject:_speechVoice forKey:@"speechVoice"]; 
     156 
     157        if( _uniqueIdentifier ) 
     158                [dictionary setObject:_uniqueIdentifier forKey:@"uniqueIdentifier"]; 
     159 
     160        if( _person && [_person uniqueId] ) 
     161                [dictionary setObject:[_person uniqueId] forKey:@"addressBookPersonRecord"]; 
     162 
     163        return [dictionary autorelease]; 
     164
     165 
     166#pragma mark - 
     167 
     168- (void) registerWithConnection:(MVChatConnection *) connection { 
     169        NSEnumerator *enumerator = [_rules objectEnumerator]; 
     170        MVChatUserWatchRule *rule = nil; 
     171 
     172        while( ( rule = [enumerator nextObject] ) ) { 
     173                if( [[rule applicableServerDomains] count] ) { 
     174                        NSEnumerator *domainEnumerator = [[rule applicableServerDomains] objectEnumerator]; 
     175                        NSString *domain = nil; 
     176 
     177                        while( ( domain = [domainEnumerator nextObject] ) ) { 
     178                                if( [[connection server] compare:domain options:( NSCaseInsensitiveSearch | NSLiteralSearch | NSBackwardsSearch | NSAnchoredSearch )] == NSOrderedSame ) { 
     179                                        [connection addChatUserWatchRule:rule]; 
     180                                        break; 
     181                                } 
     182                        } 
     183                } else [connection addChatUserWatchRule:rule]; 
     184        } 
     185
    80186 
    81187- (void) registerWithApplicableConnections { 
     
    105211} 
    106212 
     213- (void) unregisterWithConnection:(MVChatConnection *) connection { 
     214        NSEnumerator *enumerator = [_rules objectEnumerator]; 
     215        MVChatUserWatchRule *rule = nil; 
     216 
     217        while( ( rule = [enumerator nextObject] ) ) 
     218                [connection removeChatUserWatchRule:rule]; 
     219} 
     220 
    107221- (void) unregisterWithApplicableConnections { 
    108222        NSEnumerator *enumerator = [_rules objectEnumerator]; 
     
    110224 
    111225        while( ( rule = [enumerator nextObject] ) ) { 
    112                 if( [[rule applicableServerDomains] count] ) { 
    113                         NSEnumerator *domainEnumerator = [[rule applicableServerDomains] objectEnumerator]; 
    114                         NSString *domain = nil; 
    115  
    116                         while( ( domain = [domainEnumerator nextObject] ) ) { 
    117                                 NSEnumerator *connectionEnumerator = [[[MVConnectionsController defaultController] connectionsForServerAddress:domain] objectEnumerator]; 
    118                                 MVChatConnection *connection = nil; 
    119  
    120                                 while( ( connection = [connectionEnumerator nextObject] ) ) 
    121                                         [connection removeChatUserWatchRule:rule]; 
    122                         } 
    123                 } else { 
    124                         NSEnumerator *connectionEnumerator = [[[MVConnectionsController defaultController] connections] objectEnumerator]; 
    125                         MVChatConnection *connection = nil; 
    126  
    127                         while( ( connection = [connectionEnumerator nextObject] ) ) 
    128                                 [connection removeChatUserWatchRule:rule]; 
    129                 } 
     226                NSEnumerator *connectionEnumerator = [[[MVConnectionsController defaultController] connections] objectEnumerator]; 
     227                MVChatConnection *connection = nil; 
     228 
     229                while( ( connection = [connectionEnumerator nextObject] ) ) 
     230                        [connection removeChatUserWatchRule:rule]; 
    130231        } 
    131232} 
     
    138239 
    139240- (void) setActiveUser:(MVChatUser *) user { 
    140         [_activeUser autorelease]
     241        id old = _activeUser
    141242        _activeUser = [user retain]; 
     243        [old release]; 
    142244} 
    143245 
     
    155257 
    156258- (BOOL) isOnline { 
    157         return ( [_users count] > 0 ? YES : NO ); 
     259        return ( [_users count] > 0 ); 
    158260} 
    159261 
     
    178280                default: 
    179281                case JVBuddyFullName: 
    180                         return [self compositeName]; 
     282                        if( [[self compositeName] length] ) 
     283                                return [self compositeName]; 
    181284                case JVBuddyGivenNickname: 
    182285                        if( [[self givenNickname] length] ) 
     
    216319 
    217320- (NSImage *) picture { 
    218         return [[[NSImage alloc] initWithData:[_person imageData]] autorelease]; 
     321        if( _picture ) 
     322                return _picture; 
     323        if( _person ) 
     324                return [[[NSImage alloc] initWithData:[_person imageData]] autorelease]; 
     325        return nil; 
    219326} 
    220327 
    221328- (void) setPicture:(NSImage *) picture { 
    222         [_person setImageData:[picture TIFFRepresentation]]; 
     329        id old = _picture; 
     330        _picture = [picture copyWithZone:nil]; 
     331        [old release]; 
    223332} 
    224333 
     
    229338        NSString *lastName = [self lastName]; 
    230339 
    231         if( ! firstName && lastName ) return lastName; 
    232         else if( firstName && ! lastName ) return firstName; 
    233         else if( firstName && lastName ) { 
     340        if( ! [firstName length] && [lastName length] ) 
     341                return lastName; 
     342        if( [firstName length] && ! [lastName length] ) 
     343                return firstName; 
     344        if( [firstName length] && [lastName length] ) 
    234345                return [NSString stringWithFormat:@"%@ %@", firstName, lastName]; 
    235         } 
    236346 
    237347        firstName = [self givenNickname]; 
    238         if( [firstName length] ) return firstName; 
     348        if( [firstName length] ) 
     349                return firstName; 
    239350 
    240351        return [[self activeUser] nickname]; 
     
    242353 
    243354- (NSString *) firstName { 
    244         return [_person valueForProperty:kABFirstNameProperty]; 
     355        if( _firstName ) return _firstName; 
     356        if( _person ) return [_person valueForProperty:kABFirstNameProperty]; 
     357        return nil; 
    245358} 
    246359 
    247360- (NSString *) lastName { 
    248         return [_person valueForProperty:kABLastNameProperty]; 
     361        if( _lastName ) return _lastName; 
     362        if( _person ) return [_person valueForProperty:kABLastNameProperty]; 
     363        return nil; 
    249364} 
    250365 
    251366- (NSString *) primaryEmail { 
    252         ABMultiValue *value = [_person valueForProperty:kABEmailProperty]; 
    253         return [value valueAtIndex:[value indexForIdentifier:[value primaryIdentifier]]]; 
     367        if( _primaryEmail ) return _primaryEmail; 
     368 
     369        if( _person ) { 
     370                ABMultiValue *value = [_person valueForProperty:kABEmailProperty]; 
     371                return [value valueAtIndex:[value indexForIdentifier:[value primaryIdentifier]]]; 
     372        } 
     373 
     374        return nil; 
    254375} 
    255376 
    256377- (NSString *) givenNickname { 
    257         return [_person valueForProperty:kABNicknameProperty]; 
     378        if( _givenNickname ) return _givenNickname; 
     379        if( _person ) return [_person valueForProperty:kABNicknameProperty]; 
     380        return nil; 
    258381} 
    259382 
    260383- (NSString *) speechVoice { 
    261         return [_person valueForProperty:JVBuddyAddressBookSpeechVoiceProperty]; 
     384        return _speechVoice; 
     385
     386 
     387- (NSString *) uniqueIdentifier { 
     388        return _uniqueIdentifier; 
    262389} 
    263390 
     
    265392 
    266393- (void) setFirstName:(NSString *) name { 
    267         [_person setValue:name forProperty:kABFirstNameProperty]; 
    268         [[ABAddressBook sharedAddressBook] save]; 
     394        id old = _firstName; 
     395        _firstName = [name copyWithZone:nil]; 
     396        [old release]; 
    269397} 
    270398 
    271399- (void) setLastName:(NSString *) name { 
    272         [_person setValue:name forProperty:kABLastNameProperty]; 
    273         [[ABAddressBook sharedAddressBook] save]; 
     400        id old = _lastName; 
     401        _lastName = [name copyWithZone:nil]; 
     402        [old release]; 
    274403} 
    275404 
    276405- (void) setPrimaryEmail:(NSString *) email { 
    277         ABMutableMultiValue *value = [[[_person valueForProperty:kABEmailProperty] mutableCopy] autorelease]; 
    278  
    279         if( ! value ) { 
    280                 value = [[[ABMutableMultiValue alloc] init] autorelease]; 
    281                 [value addValue:email withLabel:kABOtherLabel]; 
    282         } else [value replaceValueAtIndex:[value indexForIdentifier:[value primaryIdentifier]] withValue:email]; 
    283  
    284         [_person setValue:value forProperty:kABEmailProperty]; 
    285         [[ABAddressBook sharedAddressBook] save]; 
     406        id old = _primaryEmail; 
     407        _primaryEmail = [email copyWithZone:nil]; 
     408        [old release]; 
    286409} 
    287410 
    288411- (void) setGivenNickname:(NSString *) name { 
    289         [_person setValue:name forProperty:kABNicknameProperty]; 
    290         [[ABAddressBook sharedAddressBook] save]; 
     412        id old = _givenNickname; 
     413        _givenNickname = [name copyWithZone:nil]; 
     414        [old release]; 
    291415} 
    292416 
    293417- (void) setSpeechVoice:(NSString *) voice { 
    294         if( [voice length] ) [_person setValue:voice forProperty:JVBuddyAddressBookSpeechVoiceProperty];         
    295         else [_person removeValueForProperty:JVBuddyAddressBookSpeechVoiceProperty];     
    296         [[ABAddressBook sharedAddressBook] save]; 
    297 
    298  
    299 #pragma mark - 
    300  
    301 - (NSString *) uniqueIdentifier { 
    302         return [_person uniqueId]; 
    303 
    304  
    305 - (ABPerson *) person { 
     418        id old = _speechVoice; 
     419        _speechVoice = [voice copyWithZone:nil]; 
     420        [old release]; 
     421
     422 
     423#pragma mark - 
     424 
     425- (ABPerson *) addressBookPersonRecord { 
    306426        return _person; 
    307427} 
     
    410530        [_users addObject:user]; 
    411531 
    412         if( [self status] != MVChatUserAvailableStatus || [self status] != MVChatUserAwayStatus ) [self setActiveUser:user]; 
     532        if( [self status] != MVChatUserAvailableStatus && [self status] != MVChatUserAwayStatus ) [self setActiveUser:user]; 
    413533        if( cameOnline ) [[NSNotificationCenter defaultCenter] postNotificationName:JVBuddyCameOnlineNotification object:self userInfo:nil]; 
    414534} 
     
    418538        [_users removeObject:user]; 
    419539 
    420         if( [[self activeUser] isEqualToChatUser:user] ) { 
    421                 if( [_users count] ) [self setActiveUser:[_users lastObject]]; 
    422                 else [self setActiveUser:nil]; 
    423         } 
     540        if( [[self activeUser] isEqualToChatUser:user] ) 
     541                [self setActiveUser:[_users lastObject]]; 
    424542 
    425543        if( ! [_users count] ) [[NSNotificationCenter defaultCenter] postNotificationName:JVBuddyWentOfflineNotification object:self userInfo:nil]; 
     
    440558- (void) _registerWithConnection:(NSNotification *) notification { 
    441559        MVChatConnection *connection = [notification object]; 
    442         NSEnumerator *enumerator = [_rules objectEnumerator]; 
    443         MVChatUserWatchRule *rule = nil; 
    444  
    445         while( ( rule = [enumerator nextObject] ) ) { 
    446                 if( [[rule applicableServerDomains] count] ) { 
    447                         NSEnumerator *domainEnumerator = [[rule applicableServerDomains] objectEnumerator]; 
    448                         NSString *domain = nil; 
    449  
    450                         while( ( domain = [domainEnumerator nextObject] ) ) { 
    451                                 if( [[connection server] compare:domain options:( NSCaseInsensitiveSearch | NSLiteralSearch | NSBackwardsSearch | NSAnchoredSearch )] == NSOrderedSame ) 
    452                                         [connection addChatUserWatchRule:rule]; 
    453                         } 
    454                 } else [connection addChatUserWatchRule:rule]; 
    455         } 
     560        [self registerWithConnection:connection]; 
    456561} 
    457562 
     
    461566        MVChatUser *user = nil; 
    462567 
    463         while( ( user = [enumerator nextObject] ) ) { 
    464                 if( [[user connection] isEqual:connection] ) { 
     568        while( ( user = [enumerator nextObject] ) ) 
     569                if( [[user connection] isEqual:connection] ) 
    465570                        [_users removeObject:user]; 
    466                         if( ! [_users count] ) [[NSNotificationCenter defaultCenter] postNotificationName:JVBuddyWentOfflineNotification object:self userInfo:nil]; 
    467                 } 
    468         } 
    469571 
    470572        if( [[[self activeUser] connection] isEqual:connection] ) 
    471573                [self setActiveUser:[_users lastObject]]; 
     574 
     575        if( ! [_users count] ) 
     576                [[NSNotificationCenter defaultCenter] postNotificationName:JVBuddyWentOfflineNotification object:self userInfo:nil]; 
    472577} 
    473578 
     
    475580        MVChatUser *user = [[notification userInfo] objectForKey:@"user"]; 
    476581 
    477         [_users addObject:user]; 
    478         if( ! [self activeUser] ) 
    479                 [self setActiveUser:user]; 
    480  
    481         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _buddyOnline: ) name:MVChatConnectionWatchedUserOfflineNotification object:user]; 
     582        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _buddyOnline: ) name:MVChatConnectionWatchedUserOnlineNotification object:user]; 
    482583        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _buddyOffline: ) name:MVChatConnectionWatchedUserOfflineNotification object:user]; 
    483584        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _buddyIdleUpdate: ) name:MVChatUserIdleTimeUpdatedNotification object:user];