Adium

Changeset 15618

Show
Ignore:
Timestamp:
03/29/2006 02:15:12 AM (3 years ago)
Author:
kiel
Message:

Providing a Block/Unblock toolbar item for message windows. Closes 1117.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Adium.xcodeproj/project.pbxproj

    r15611 r15618  
    13521352                9EA125E9055B630900ECF349 /* CBGaimOscarAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = 9EA125E8055B630900ECF349 /* CBGaimOscarAccount.m */; }; 
    13531353                9EA125EF055B633000ECF349 /* CBGaimOscarAccount.h in Headers */ = {isa = PBXBuildFile; fileRef = 9EA125EE055B633000ECF349 /* CBGaimOscarAccount.h */; }; 
     1354                9EF0DBFA09D944C200FBCC1E /* block.png in Resources */ = {isa = PBXBuildFile; fileRef = 9EF0DBF309D944A300FBCC1E /* block.png */; }; 
     1355                9EF0DBFB09D944C200FBCC1E /* unblock.png in Resources */ = {isa = PBXBuildFile; fileRef = 9EF0DBF409D944A300FBCC1E /* unblock.png */; }; 
    13541356                A3C042D208D7483100B48CE1 /* GaimDefaultsGTalk.plist in Resources */ = {isa = PBXBuildFile; fileRef = A3C042D108D7483100B48CE1 /* GaimDefaultsGTalk.plist */; }; 
    13551357                A3C0432108D74D3100B48CE1 /* AIGaimGTalkAccount.h in Headers */ = {isa = PBXBuildFile; fileRef = A3C0431B08D74D3100B48CE1 /* AIGaimGTalkAccount.h */; }; 
     
    34833485                9EB3C53304F94FAE001D1F74 /* CBOldPrefsImporterAppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CBOldPrefsImporterAppController.h; sourceTree = "<group>"; }; 
    34843486                9EB3C53404F94FAE001D1F74 /* CBOldPrefsImporterAppController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CBOldPrefsImporterAppController.m; sourceTree = "<group>"; }; 
     3487                9EF0DBF309D944A300FBCC1E /* block.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = block.png; sourceTree = "<group>"; }; 
     3488                9EF0DBF409D944A300FBCC1E /* unblock.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = unblock.png; sourceTree = "<group>"; }; 
    34853489                A3C042D108D7483100B48CE1 /* GaimDefaultsGTalk.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = GaimDefaultsGTalk.plist; path = "Plugins/Gaim Service/GaimDefaultsGTalk.plist"; sourceTree = "<group>"; }; 
    34863490                A3C0431B08D74D3100B48CE1 /* AIGaimGTalkAccount.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AIGaimGTalkAccount.h; path = "Plugins/Gaim Service/AIGaimGTalkAccount.h"; sourceTree = "<group>"; }; 
     
    48504854                        children = ( 
    48514855                                110763F908676D04005987A5 /* BlockEditorWindow.nib */, 
     4856                                9EF0DBF309D944A300FBCC1E /* block.png */, 
     4857                                9EF0DBF409D944A300FBCC1E /* unblock.png */, 
    48524858                                110763F108676CC9005987A5 /* RAFBlockEditorPlugin.h */, 
    48534859                                110763F208676CC9005987A5 /* RAFBlockEditorPlugin.m */, 
     
    82938299                        buildActionMask = 2147483647; 
    82948300                        files = ( 
     8301                                9EF0DBFA09D944C200FBCC1E /* block.png in Resources */, 
     8302                                9EF0DBFB09D944C200FBCC1E /* unblock.png in Resources */, 
    82958303                                346F5CB408A418FB0055C610 /* iTunes.png in Resources */, 
    82968304                                346F5D3208A43E7B0055C610 /* CurrentTunes.scpt in Resources */, 
  • trunk/Source/ESBlockingPlugin.h

    r11658 r15618  
    1717#import <Adium/AIPlugin.h> 
    1818 
    19 @interface ESBlockingPlugin : AIPlugin
     19@interface ESBlockingPlugin : AIPlugin <AIListObjectObserver>
    2020        NSMenuItem  *blockContactMenuItem; 
    2121        NSMenuItem  *blockContactContextualMenuItem; 
     22         
     23        NSMutableSet    *chatToolbarItems; 
     24        NSDictionary    *blockedToolbarIcons; 
    2225} 
    2326 
  • trunk/Source/ESBlockingPlugin.m

    r15210 r15618  
    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> 
     26#import <AIUtilities/AIImageAdditions.h> 
    2227#import <Adium/AIAccount.h> 
    2328#import <Adium/AIListContact.h> 
    2429#import <Adium/AIMetaContact.h> 
    25  
    26 #define BLOCK_CONTACT   AILocalizedString(@"Block","Block Contact menu item") 
    27 #define UNBLOCK_CONTACT AILocalizedString(@"Unblock","Unblock Contact menu item") 
     30#import <Adium/AIChat.h> 
     31 
     32#define BLOCK_CONTACT                           AILocalizedString(@"Block","Block Contact menu item") 
     33#define UNBLOCK_CONTACT                         AILocalizedString(@"Unblock","Unblock Contact menu item") 
     34#define TOOLBAR_ITEM_IDENTIFIER         @"chatItem" 
     35#define TOOLBAR_BLOCK_ICON_KEY          @"Block" 
     36#define TOOLBAR_UNBLOCK_ICON_KEY        @"Unblock" 
    2837 
    2938@interface ESBlockingPlugin(PRIVATE) 
     
    3140- (BOOL)_searchPrivacyListsForListContact:(AIListContact *)contact withDesiredResult:(BOOL)desiredResult; 
    3241- (void)accountConnected:(NSNotification *)notification; 
     42- (BOOL)areAllGivenContactsBlocked:(NSArray *)contacts; 
     43- (void)setPrivacy:(BOOL)block forContacts:(NSArray *)contacts; 
     44- (IBAction)blockOrUnblockParticipants:(NSToolbarItem *)senderItem; 
     45 
     46//protocols 
     47- (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent; 
     48 
     49//notifications 
     50- (void)chatDidBecomeVisible:(NSNotification *)notification; 
     51- (void)toolbarWillAddItem:(NSNotification *)notification; 
     52- (void)toolbarDidRemoveItem:(NSNotification *)notification; 
     53 
     54//toolbar item methods 
     55- (void)updateToolbarIconOfChat:(AIChat *)inChat inWindow:(NSWindow *)window; 
     56- (void)updateToolbarItem:(NSToolbarItem *)item forChat:(AIChat *)chat; 
     57- (void)updateToolbarItemForObject:(AIListObject *)inObject; 
    3358@end 
    3459 
     60#pragma mark - 
    3561@implementation ESBlockingPlugin 
    3662 
     
    3965        //Install the Block menu items 
    4066        blockContactMenuItem = [[NSMenuItem alloc] initWithTitle:BLOCK_CONTACT 
    41                                                                                                                 target:self 
    42                                                                                                                 action:@selector(blockContact:) 
    43                                                                                                  keyEquivalent:@""]; 
     67                                                                                                        target:self 
     68                                                                                                        action:@selector(blockContact:) 
     69                                                                                          keyEquivalent:@""]; 
    4470        [[adium menuController] addMenuItem:blockContactMenuItem toLocation:LOC_Contact_NegativeAction]; 
    4571 
     
    5682                                                                           name:ACCOUNT_CONNECTED 
    5783                                                                         object:nil]; 
     84         
     85        //create the block toolbar item 
     86        chatToolbarItems = [[NSMutableSet alloc] init]; 
     87        //cache toolbar icons 
     88        blockedToolbarIcons = [[NSDictionary alloc] initWithObjectsAndKeys: 
     89                                                                [NSImage imageNamed:@"block.png" forClass:[self class]], TOOLBAR_BLOCK_ICON_KEY,  
     90                                                                [NSImage imageNamed:@"unblock.png" forClass:[self class]], TOOLBAR_UNBLOCK_ICON_KEY,  
     91                                                                nil]; 
     92        NSToolbarItem   *chatItem = [AIToolbarUtilities toolbarItemWithIdentifier:TOOLBAR_ITEM_IDENTIFIER 
     93                                                                                                                                                label:BLOCK_CONTACT 
     94                                                                                                                                 paletteLabel:BLOCK_CONTACT 
     95                                                                                                                                          toolTip:BLOCK_CONTACT 
     96                                                                                                                                           target:self 
     97                                                                                                                          settingSelector:@selector(setImage:) 
     98                                                                                                                                  itemContent:[blockedToolbarIcons valueForKey:TOOLBAR_BLOCK_ICON_KEY] 
     99                                                                                                                                           action:@selector(blockOrUnblockParticipants:) 
     100                                                                                                                                                 menu:nil]; 
     101         
     102        [[adium toolbarController] registerToolbarItem:chatItem forToolbarType:@"MessageWindow"]; 
     103         
     104        [[NSNotificationCenter defaultCenter] addObserver:self 
     105                                                                                         selector:@selector(toolbarWillAddItem:) 
     106                                                                                                 name:NSToolbarWillAddItemNotification 
     107                                                                                           object:nil]; 
     108        [[NSNotificationCenter defaultCenter] addObserver:self 
     109                                                                                         selector:@selector(toolbarDidRemoveItem:) 
     110                                                                                                 name:NSToolbarDidRemoveItemNotification 
     111                                                                                           object:nil]; 
     112        [[adium contactController] registerListObjectObserver:self]; 
    58113} 
    59114 
     
    61116{ 
    62117        [[adium notificationCenter] removeObserver:self]; 
     118        [[adium contactController] unregisterListObjectObserver:self]; 
     119        [[NSNotificationCenter defaultCenter] removeObserver:self]; 
     120        [chatToolbarItems release]; 
     121        [blockedToolbarIcons release]; 
    63122        [blockContactMenuItem release]; 
    64123        [blockContactContextualMenuItem release]; 
    65124} 
    66125 
     126/*! 
     127 * @brief Block or unblock contacts 
     128 * 
     129 * @param block Flag indicating what the operation should achieve: NO for unblock, YES for block. 
     130 * @param contacts The contacts to block or unblock 
     131 */ 
     132- (void)setPrivacy:(BOOL)block forContacts:(NSArray *)contacts 
     133{ 
     134        NSEnumerator    *contactEnumerator = [contacts objectEnumerator]; 
     135        AIListContact   *currentContact = nil; 
     136         
     137        while ((currentContact = [contactEnumerator nextObject])) { 
     138                if ([currentContact isBlocked] != block) { 
     139                        [currentContact setIsBlocked:block updateList:YES]; 
     140                } 
     141        } 
     142} 
    67143 
    68144- (IBAction)blockContact:(id)sender 
     
    193269} 
    194270 
     271#pragma mark - 
    195272#pragma mark Private 
    196273//Private -------------------------------------------------------------------------------------------------------------- 
     
    259336} 
    260337 
     338/*! 
     339 * @brief Determine if all the referenced contacts are blocked or unblocked 
     340 * 
     341 * @param contacts The contacts to query 
     342 * @result A flag indicating if all the contacts are blocked or not 
     343 */ 
     344- (BOOL)areAllGivenContactsBlocked:(NSArray *)contacts 
     345{ 
     346        NSEnumerator    *contactEnumerator = [contacts objectEnumerator]; 
     347        AIListContact   *currentContact = nil; 
     348        BOOL                    areAllGivenContactsBlocked = YES; 
     349         
     350        //for each contact in the array 
     351        while ((currentContact = [contactEnumerator nextObject])) { 
     352                 
     353                //if the contact is unblocked, then all the contacts in the array aren't blocked 
     354                if (![currentContact isBlocked]) { 
     355                        areAllGivenContactsBlocked = NO; 
     356                        break; 
     357                } 
     358        } 
     359         
     360        return areAllGivenContactsBlocked; 
     361} 
     362 
     363/*! 
     364 * @brief Block or unblock participants of the active chat in a chat window 
     365 * 
     366 * If all the participants of the chat are blocked, attempt to unblock each 
     367 * Else, attempt to block those that are not already blocked. 
     368 * Then, Update the item for the chat. 
     369 * 
     370 * We have to do it this way because a user can (un)block participants of  
     371 * a chat window in the background by command-clicking the toolbar item. 
     372 * 
     373 * @param senderItem The toolbar item that received the event 
     374 */ 
     375- (IBAction)blockOrUnblockParticipants:(NSToolbarItem *)senderItem 
     376{ 
     377        NSEnumerator    *windowEnumerator = [[NSApp windows] objectEnumerator]; 
     378        NSWindow                *currentWindow = nil; 
     379        NSToolbar               *windowToolbar = nil; 
     380        NSToolbar               *senderToolbar = [senderItem toolbar]; 
     381        AIChat                  *activeChatInWindow = nil; 
     382        NSArray                 *participants = nil; 
     383         
     384        //for each open window 
     385        while ((currentWindow = [windowEnumerator nextObject])) { 
     386 
     387                //if it has a toolbar 
     388                if ((windowToolbar = [currentWindow toolbar])) { 
     389 
     390                        //do the toolbars match? 
     391                        if (windowToolbar == senderToolbar) { 
     392                                activeChatInWindow = [[adium interfaceController] activeChatInWindow:currentWindow]; 
     393                                participants = [activeChatInWindow participatingListObjects]; 
     394                                 
     395                                //do the deed 
     396                                [self setPrivacy:(![self areAllGivenContactsBlocked:participants]) forContacts:participants]; 
     397                                [self updateToolbarItem:senderItem forChat:activeChatInWindow]; 
     398                                break; 
     399                        } 
     400                } 
     401        } 
     402} 
     403 
     404#pragma mark - 
     405#pragma mark Protocols 
     406 
     407/*! 
     408 * @brief Update any chat with the list object 
     409 * 
     410 * If the list object is (un)blocked, update any chats that we my have open with it. 
     411 */ 
     412- (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent 
     413{ 
     414        if ([inModifiedKeys containsObject:@"isBlocked"]) { 
     415                [self updateToolbarItemForObject:inObject]; 
     416        } 
     417         
     418        return nil; 
     419} 
     420 
     421#pragma mark - 
     422#pragma mark Notifications 
     423 
     424/*! 
     425 * @brief Toolbar has added an instance of the chat block toolbar item 
     426 */ 
     427- (void)toolbarWillAddItem:(NSNotification *)notification 
     428{ 
     429        NSToolbarItem   *item = [[notification userInfo] objectForKey:@"item"]; 
     430         
     431        if ([[item itemIdentifier] isEqualToString:TOOLBAR_ITEM_IDENTIFIER]) { 
     432                 
     433                //If this is the first item added, start observing for chats becoming visible so we can update the item 
     434                if ([chatToolbarItems count] == 0) { 
     435                        [[adium notificationCenter] addObserver:self 
     436                                                                                   selector:@selector(chatDidBecomeVisible:) 
     437                                                                                           name:@"AIChatDidBecomeVisible" 
     438                                                                                         object:nil]; 
     439                } 
     440                 
     441                [self updateToolbarItem:item forChat:[[adium interfaceController] activeChat]]; 
     442                [chatToolbarItems addObject:item]; 
     443        } 
     444} 
     445 
     446/*! 
     447 * @brief A toolbar item was removed 
     448 */ 
     449- (void)toolbarDidRemoveItem:(NSNotification *)notification 
     450{ 
     451        NSToolbarItem   *item = [[notification userInfo] objectForKey:@"item"]; 
     452        [chatToolbarItems removeObject:item]; 
     453         
     454        if ([chatToolbarItems count] == 0) { 
     455                [[adium notificationCenter] removeObserver:self 
     456                                                                                          name:@"AIChatDidBecomeVisible" 
     457                                                                                        object:nil]; 
     458        } 
     459} 
     460 
     461/*! 
     462 * @brief A chat became visible in a window. 
     463 * 
     464 * Update the window's (un)block toolbar item to reflect the block state of a list object 
     465 * 
     466 * @param notification Notification with an AIChat object and an @"NSWindow" userInfo key 
     467 */ 
     468- (void)chatDidBecomeVisible:(NSNotification *)notification 
     469{ 
     470        [self updateToolbarIconOfChat:[notification object] 
     471                                                  inWindow:[[notification userInfo] objectForKey:@"NSWindow"]]; 
     472} 
     473 
     474#pragma mark - 
     475#pragma mark Toolbar Item Update Methods 
     476 
     477/*! 
     478 * @brief Update the toolbar icon in a chat for a particular contact 
     479 * 
     480 * @param inObject The list object we want to update the toolbar item for 
     481 */ 
     482- (void)updateToolbarItemForObject:(AIListObject *)inObject 
     483{ 
     484        AIChat          *chat = nil; 
     485        NSWindow        *window = nil; 
     486         
     487        //Update the icon in the toolbar for this contact if a chat is open and we have any toolbar items 
     488        if (([chatToolbarItems count] > 0) && 
     489                [inObject isKindOfClass:[AIListContact class]] && 
     490                (chat = [[adium chatController] existingChatWithContact:(AIListContact *)inObject]) && 
     491                (window = [[adium interfaceController] windowForChat:chat])) { 
     492                [self updateToolbarIconOfChat:chat 
     493                                                          inWindow:window]; 
     494        } 
     495} 
     496 
     497/*! 
     498 * @brief Update the toolbar item for the particpants of a particular chat 
     499 * 
     500 * @param item The toolbar item to modify 
     501 * @param chat The chat for which the participants are participating in 
     502 */ 
     503- (void)updateToolbarItem:(NSToolbarItem *)item forChat:(AIChat *)chat 
     504{ 
     505        if ([self areAllGivenContactsBlocked:[chat participatingListObjects]]) { 
     506                //assume unblock appearance 
     507                [item setLabel:UNBLOCK_CONTACT]; 
     508                [item setPaletteLabel:UNBLOCK_CONTACT]; 
     509                [item setImage:[blockedToolbarIcons valueForKey:TOOLBAR_UNBLOCK_ICON_KEY]]; 
     510        } else { 
     511                //assume block appearance 
     512                [item setLabel:BLOCK_CONTACT]; 
     513                [item setPaletteLabel:BLOCK_CONTACT]; 
     514                [item setImage:[blockedToolbarIcons valueForKey:TOOLBAR_BLOCK_ICON_KEY]]; 
     515        } 
     516} 
     517 
     518/*! 
     519 * @brief Update the (un)block toolbar icon in a chat 
     520 * 
     521 * @param chat The chat with the participants 
     522 * @param window The window in which the chat resides 
     523 */ 
     524- (void)updateToolbarIconOfChat:(AIChat *)chat inWindow:(NSWindow *)window 
     525{ 
     526        NSToolbar               *toolbar = [window toolbar]; 
     527        NSEnumerator    *enumerator = [[toolbar items] objectEnumerator]; 
     528        NSToolbarItem   *item; 
     529         
     530        while ((item = [enumerator nextObject])) { 
     531                if ([[item itemIdentifier] isEqualToString:TOOLBAR_ITEM_IDENTIFIER]) { 
     532                        [self updateToolbarItem:item forChat:chat]; 
     533                        break; 
     534                } 
     535        } 
     536} 
     537 
    261538@end