Adium

Ticket #1117: huh.diff

File huh.diff, 10.3 kB (added by kiel, 3 years ago)

Blasted patch

  • /Users/kiel/adium/Source/ESBlockingPlugin.m

    old new  
    1717#import "AIAccountController.h" 
    1818#import "AIContactController.h" 
    1919#import "AIMenuController.h" 
     20#import "AIToolbarController.h" 
     21#import "AIInterfaceController.h" 
     22#import "AIChatController.h" 
    2023#import "ESBlockingPlugin.h" 
    2124#import <AIUtilities/AIMenuAdditions.h> 
     25#import <AIUtilities/AIToolbarUtilities.h> 
    2226#import <Adium/AIAccount.h> 
    2327#import <Adium/AIListContact.h> 
    2428#import <Adium/AIMetaContact.h> 
     29#import <Adium/AIChat.h> 
    2530 
    2631#define BLOCK_CONTACT   AILocalizedString(@"Block","Block Contact menu item") 
    2732#define UNBLOCK_CONTACT AILocalizedString(@"Unblock","Unblock Contact menu item") 
    2833 
     34NSString * ITEM_IDENTIFIER = @"chatItem"; 
     35 
    2936@interface ESBlockingPlugin(PRIVATE) 
    3037- (void)_blockContact:(AIListContact *)contact unblock:(BOOL)unblock; 
    3138- (BOOL)_searchPrivacyListsForListContact:(AIListContact *)contact withDesiredResult:(BOOL)desiredResult; 
    3239- (void)accountConnected:(NSNotification *)notification; 
     40- (BOOL)allContactsBlocked:(NSArray *)contacts; 
     41- (void)blockOrUnblockParticipants:(id)senderItem; 
     42 
     43//protocols 
     44- (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent; 
     45//- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem; 
     46 
     47//notifications 
     48- (void)chatDidBecomeVisible:(NSNotification *)notification; 
     49- (void)toolbarWillAddItem:(NSNotification *)notification; 
     50- (void)toolbarDidRemoveItem:(NSNotification *)notification; 
     51 
     52//toolbar item methods 
     53- (void)updateToolbarIconOfChat:(AIChat *)inChat inWindow:(NSWindow *)window; 
     54- (void)updateToolbarItem:(NSToolbarItem *)item forChat:(AIChat *)chat; 
     55- (void)updateToolbarItemForObject:(AIListObject *)inObject; 
    3356@end 
    3457 
     58#pragma mark - 
    3559@implementation ESBlockingPlugin 
    3660 
    3761- (void)installPlugin 
     
    5579                                                                   selector:@selector(accountConnected:) 
    5680                                                                           name:ACCOUNT_CONNECTED 
    5781                                                                         object:nil]; 
     82         
     83        //create the block toolbar item 
     84        chatToolbarItems = [[NSMutableSet alloc] init]; 
     85        NSToolbarItem   *chatItem = [AIToolbarUtilities toolbarItemWithIdentifier:ITEM_IDENTIFIER 
     86                                                                                                                                                label:BLOCK_CONTACT 
     87                                                                                                                                 paletteLabel:BLOCK_CONTACT 
     88                                                                                                                                          toolTip:BLOCK_CONTACT 
     89                                                                                                                                           target:self 
     90                                                                                                                          settingSelector:@selector(setImage:) 
     91                                                                                                                                  itemContent:[NSImage imageNamed:@"remove.png"] 
     92                                                                                                                                           action:@selector(blockOrUnblockParticipants:) 
     93                                                                                                                                                 menu:nil]; 
     94        [[adium toolbarController] registerToolbarItem:chatItem forToolbarType:@"MessageWindow"]; 
     95         
     96        [[NSNotificationCenter defaultCenter] addObserver:self 
     97                                                                                         selector:@selector(toolbarWillAddItem:) 
     98                                                                                                 name:NSToolbarWillAddItemNotification 
     99                                                                                           object:nil]; 
     100        [[NSNotificationCenter defaultCenter] addObserver:self 
     101                                                                                         selector:@selector(toolbarDidRemoveItem:) 
     102                                                                                                 name:NSToolbarDidRemoveItemNotification 
     103                                                                                           object:nil]; 
     104        [[adium contactController] registerListObjectObserver:self]; 
    58105} 
    59106 
    60107- (void)uninstallPlugin 
    61108{ 
    62109        [[adium notificationCenter] removeObserver:self]; 
     110        [[adium contactController] unregisterListObjectObserver:self]; 
     111        [[NSNotificationCenter defaultCenter] removeObserver:self]; 
     112        [chatToolbarItems release]; 
    63113        [blockContactMenuItem release]; 
    64114        [blockContactContextualMenuItem release]; 
    65115} 
    66116 
     117/*! 
     118 * @brief Block or unblock contacts 
     119 * 
     120 * @param contacts The contacts to block or unblock 
     121 * @param block Flag indicating what the operation should achieve: NO for unblock, YES for block. 
     122 */ 
     123- (void)contacts:(NSArray *)contacts blockOrUnblock:(BOOL)block 
     124{ 
     125        NSEnumerator    *contactEnumerator = [contacts objectEnumerator]; 
     126        AIListContact   *currentContact = nil; 
     127         
     128        while ((currentContact = [contactEnumerator nextObject])) { 
     129                if ([currentContact isBlocked] != block) { 
     130                        [currentContact setIsBlocked:block updateList:YES]; 
     131                } 
     132        } 
     133} 
    67134 
    68135- (IBAction)blockContact:(id)sender 
    69136{ 
     
    192259        return NO; 
    193260} 
    194261 
     262#pragma mark - 
    195263#pragma mark Private 
    196264//Private -------------------------------------------------------------------------------------------------------------- 
    197265 
     
    258326        } 
    259327} 
    260328 
     329/*! 
     330 * @brief Determine if all the referenced contacts are blocked or unblocked 
     331 * 
     332 * @param contacts The contacts to query 
     333 * @result A flag indicating if all the contacts are blocked or not 
     334 */ 
     335- (BOOL)allContactsBlocked:(NSArray *)contacts 
     336{ 
     337        NSEnumerator    *contactEnumerator = [contacts objectEnumerator]; 
     338        AIListContact   *currentContact = nil; 
     339        BOOL                    allContactsBlocked = YES; 
     340         
     341        //for each contact in the array 
     342        while ((currentContact = [contactEnumerator nextObject])) { 
     343                 
     344                //if the contact is unblocked, then all the contacts in the array aren't blocked 
     345                if (![currentContact isBlocked]) { 
     346                        allContactsBlocked = NO; 
     347                        break; 
     348                } 
     349        } 
     350         
     351        return allContactsBlocked; 
     352} 
     353 
     354/*! 
     355 * @brief Block or unblock participants of the active chat in a chat window 
     356 * 
     357 * If all the participants of the chat are blocked, attempt to unblock each 
     358 * Else, attempt to block those that are not already blocked. 
     359 * Then, Update the item for the chat. 
     360 * 
     361 * We have to do it this way because a user can (un)block participants of  
     362 * a chat window in the background by command-clicking the toolbar item. 
     363 * 
     364 * @param senderItem The toolbar item that received the event 
     365 */ 
     366- (void)blockOrUnblockParticipants:(id)senderItem 
     367{ 
     368        NSEnumerator    *windowEnumerator = [[NSApp windows] objectEnumerator]; 
     369        NSWindow                *currentWindow = nil; 
     370        NSToolbar               *windowToolbar = nil; 
     371        NSToolbar               *senderToolbar = [senderItem toolbar]; 
     372        AIChat                  *activeChatInWindow = nil; 
     373        NSArray                 *participants = nil; 
     374         
     375        //for each open window 
     376        while ((currentWindow = [windowEnumerator nextObject])) { 
     377                 
     378                //if it has a toolbar 
     379                if ((windowToolbar = [currentWindow toolbar])) { 
     380                         
     381                        //look for the sender in the current toolbar 
     382                        if (windowToolbar == senderToolbar) { 
     383                                activeChatInWindow = [[adium interfaceController] activeChatInWindow:currentWindow]; 
     384                                participants = [activeChatInWindow participatingListObjects]; 
     385                                 
     386                                //do the deed 
     387                                [self contacts:participants blockOrUnblock:(![self allContactsBlocked:participants])]; 
     388                                [self updateToolbarIconOfChat:activeChatInWindow inWindow:currentWindow]; 
     389                                break; 
     390                        } 
     391                } 
     392        } 
     393} 
     394 
     395#pragma mark - 
     396#pragma mark Protocols 
     397 
     398/*! 
     399 * @brief Update any chat with the list object 
     400 * 
     401 * If the list object is (un)blocked, update any chats that we my have open with it. 
     402 */ 
     403- (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent 
     404{ 
     405        if ([inModifiedKeys containsObject:@"isBlocked"]) { 
     406                [self updateToolbarItemForObject:inObject]; 
     407        } 
     408         
     409        return nil; 
     410} 
     411 
     412#pragma mark - 
     413#pragma mark Notifications 
     414 
     415/*! 
     416 * @brief Toolbar has added an instance of the chat block toolbar item 
     417 */ 
     418- (void)toolbarWillAddItem:(NSNotification *)notification 
     419{ 
     420        NSToolbarItem   *item = [[notification userInfo] objectForKey:@"item"]; 
     421         
     422        if ([[item itemIdentifier] isEqualToString:ITEM_IDENTIFIER]) { 
     423                 
     424                //If this is the first item added, start observing for chats becoming visible so we can update the item 
     425                if ([chatToolbarItems count] == 0) { 
     426                        [[adium notificationCenter] addObserver:self 
     427                                                                                   selector:@selector(chatDidBecomeVisible:) 
     428                                                                                           name:@"AIChatDidBecomeVisible" 
     429                                                                                         object:nil]; 
     430                } 
     431                 
     432                [chatToolbarItems addObject:item]; 
     433        } 
     434} 
     435 
     436/*! 
     437 * @brief A toolbar item was removed 
     438 */ 
     439- (void)toolbarDidRemoveItem:(NSNotification *)notification 
     440{ 
     441        NSToolbarItem   *item = [[notification userInfo] objectForKey:@"item"]; 
     442        [chatToolbarItems removeObject:item]; 
     443         
     444        if ([chatToolbarItems count] == 0) { 
     445                [[adium notificationCenter] removeObserver:self 
     446                                                                                          name:@"AIChatDidBecomeVisible" 
     447                                                                                        object:nil]; 
     448        } 
     449} 
     450 
     451/*! 
     452 * @brief A chat became visible in a window. 
     453 * 
     454 * Update the window's (un)block toolbar item to reflect the block state of a list object 
     455 * 
     456 * @param notification Notification with an AIChat object and an @"NSWindow" userInfo key 
     457 */ 
     458- (void)chatDidBecomeVisible:(NSNotification *)notification 
     459{ 
     460        //NSLog(@"chat did become visible: %@", notification); 
     461        [self updateToolbarIconOfChat:[notification object] 
     462                                                  inWindow:[[notification userInfo] objectForKey:@"NSWindow"]]; 
     463} 
     464 
     465#pragma mark - 
     466#pragma mark Toolbar Item Update Methods 
     467 
     468/*! 
     469 * @brief Update the toolbar icon in a chat for a particular contact 
     470 * 
     471 * @param inObject The list object we want to update the toolbar item for 
     472 */ 
     473- (void)updateToolbarItemForObject:(AIListObject *)inObject 
     474{ 
     475        AIChat          *chat = nil; 
     476        NSWindow        *window = nil; 
     477         
     478        //Update the icon in the toolbar for this contact if a chat is open and we have any toolbar items 
     479        if (([chatToolbarItems count] > 0) && 
     480                [inObject isKindOfClass:[AIListContact class]] && 
     481                (chat = [[adium chatController] existingChatWithContact:(AIListContact *)inObject]) && 
     482                (window = [[adium interfaceController] windowForChat:chat])) { 
     483                [self updateToolbarIconOfChat:chat 
     484                                                          inWindow:window]; 
     485        } 
     486} 
     487 
     488/*! 
     489 * @brief Update the toolbar item for the particpants of a particular chat 
     490 * 
     491 * @param item The toolbar item to modify 
     492 * @param chat The chat for which the participants are participating in 
     493 */ 
     494- (void)updateToolbarItem:(NSToolbarItem *)item forChat:(AIChat *)chat 
     495{ 
     496        if ([self allContactsBlocked:[chat participatingListObjects]]) { 
     497                //assume unblock appearance 
     498                [item setLabel:UNBLOCK_CONTACT]; 
     499                [item setPaletteLabel:UNBLOCK_CONTACT]; 
     500        } else { 
     501                //assume block appearance 
     502                [item setLabel:BLOCK_CONTACT]; 
     503                [item setPaletteLabel:BLOCK_CONTACT]; 
     504        } 
     505         
     506        NSLog(@"%@", [item view]); 
     507} 
     508 
     509/*! 
     510 * @brief Update the (un)block toolbar icon in a chat 
     511 * 
     512 * @param chat The chat with the participants 
     513 * @param window The window in which the chat resides 
     514 */ 
     515- (void)updateToolbarIconOfChat:(AIChat *)chat inWindow:(NSWindow *)window 
     516{ 
     517        NSToolbar               *toolbar = [window toolbar]; 
     518        NSEnumerator    *enumerator = [[toolbar items] objectEnumerator]; 
     519        NSToolbarItem   *item; 
     520         
     521        while ((item = [enumerator nextObject])) { 
     522                if ([[item itemIdentifier] isEqualToString:ITEM_IDENTIFIER]) { 
     523                        [self updateToolbarItem:item forChat:chat]; 
     524                        break; 
     525                } 
     526        } 
     527} 
     528 
    261529@end