2 * Adium is the legal property of its developers, whose names are listed in the copyright file included
3 * with this source distribution.
5 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * General Public License as published by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
11 * Public License for more details.
13 * You should have received a copy of the GNU General Public License along with this program; if not,
14 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 #import "AIAccountController.h"
18 #import "AIContactController.h"
19 #import "AIMenuController.h"
20 #import "ESBlockingPlugin.h"
21 #import <AIUtilities/AIMenuAdditions.h>
22 #import <Adium/AIAccount.h>
23 #import <Adium/AIListContact.h>
24 #import <Adium/AIMetaContact.h>
26 #define BLOCK_CONTACT AILocalizedString(@"Block","Block Contact menu item")
27 #define UNBLOCK_CONTACT AILocalizedString(@"Unblock","Unblock Contact menu item")
29 @interface ESBlockingPlugin(PRIVATE)
30 - (void)_blockContact:(AIListContact *)contact unblock:(BOOL)unblock;
31 - (BOOL)_searchPrivacyListsForListContact:(AIListContact *)contact withDesiredResult:(BOOL)desiredResult;
34 @implementation ESBlockingPlugin
38 //Install the Block menu items
39 blockContactMenuItem = [[NSMenuItem alloc] initWithTitle:BLOCK_CONTACT
41 action:@selector(blockContact:)
43 [[adium menuController] addMenuItem:blockContactMenuItem toLocation:LOC_Contact_NegativeAction];
45 //Add our get info contextual menu items
46 blockContactContextualMenuItem = [[NSMenuItem alloc] initWithTitle:BLOCK_CONTACT
48 action:@selector(blockContact:)
50 [[adium menuController] addContextualMenuItem:blockContactContextualMenuItem toLocation:Context_Contact_NegativeAction];
53 - (void)uninstallPlugin
55 [blockContactMenuItem release];
56 [blockContactContextualMenuItem release];
60 - (IBAction)blockContact:(id)sender
65 if(sender == blockContactMenuItem){
66 object = [[adium contactController] selectedListObject];
68 object = [[adium menuController] currentContextMenuObject];
71 unblock = [[sender title] isEqualToString:UNBLOCK_CONTACT];
74 if([object isKindOfClass:[AIListContact class]]){
75 AIListContact *contact = (AIListContact *)object;
76 NSString *format = unblock
77 ? AILocalizedString(@"Are you sure you want to unblock %@?",nil)
78 : AILocalizedString(@"Are you sure you want to block %@?",nil);
80 if(NSRunAlertPanel([NSString stringWithFormat:format, [contact displayName]],
82 AILocalizedString(@"OK",nil),
83 AILocalizedString(@"Cancel",nil),
85 == NSAlertDefaultReturn){
88 if([object isKindOfClass:[AIMetaContact class]]){
89 AIMetaContact *meta = (AIMetaContact *)object;
91 //Enumerate over the various list contacts contained
92 NSEnumerator *enumerator = [[meta listContacts] objectEnumerator];
93 AIListContact *containedContact = nil;
95 while((containedContact = [enumerator nextObject])){
96 AIAccount <AIAccount_Privacy> *acct = [containedContact account];
97 if([acct conformsToProtocol:@protocol(AIAccount_Privacy)]) {
98 [self _blockContact:contact unblock:unblock];
100 NSLog(@"Account %@ does not support blocking (contact %@ not blocked on this account)", acct, containedContact);
104 AIListContact *contact = (AIListContact *)object;
105 AIAccount <AIAccount_Privacy> *acct = [contact account];
106 if([acct conformsToProtocol:@protocol(AIAccount_Privacy)]) {
107 [self _blockContact:contact unblock:unblock];
109 NSLog(@"Account %@ does not support blocking (contact %@ not blocked on this account)", acct, contact);
116 - (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem
118 AIListObject *object;
119 BOOL unblock = [[menuItem title] isEqualToString:UNBLOCK_CONTACT];
120 BOOL anyAccount = NO;
122 if(menuItem == blockContactMenuItem){
123 object = [[adium contactController] selectedListObject];
125 object = [[adium menuController] currentContextMenuObject];
129 if([object isKindOfClass:[AIListContact class]]){
131 if([object isKindOfClass:[AIMetaContact class]]){
132 AIMetaContact *meta = (AIMetaContact *)object;
134 //Enumerate over the various list contacts contained
135 NSEnumerator *enumerator = [[meta listContacts] objectEnumerator];
136 AIListContact *contact = nil;
138 while((contact = [enumerator nextObject])){
139 AIAccount <AIAccount_Privacy> *acct = [contact account];
140 if([acct conformsToProtocol:@protocol(AIAccount_Privacy)]){
142 if([[acct listObjectIDsOnPrivacyList:PRIVACY_DENY] containsObject:[contact UID]]){
143 //title: "Unblock"; enabled
145 [menuItem setTitle:UNBLOCK_CONTACT];
152 //title: "Block"; enabled
154 [menuItem setTitle:BLOCK_CONTACT];
158 //title: "Block"; disabled
159 [menuItem setTitle:BLOCK_CONTACT];
163 AIListContact *contact = (AIListContact *)object;
164 AIAccount <AIAccount_Privacy> *acct = [contact account];
165 if([acct conformsToProtocol:@protocol(AIAccount_Privacy)]){
166 if([[acct listObjectIDsOnPrivacyList:PRIVACY_DENY] containsObject:[contact UID]]){
167 //title: "Unblock"; enabled
169 [menuItem setTitle:UNBLOCK_CONTACT];
173 //title: "Block"; enabled
175 [menuItem setTitle:BLOCK_CONTACT];
180 //title: "Block"; disabled
181 [menuItem setTitle:BLOCK_CONTACT];
190 //Private --------------------------------------------------------------------------------------------------------------
192 - (void)_blockContact:(AIListContact *)contact unblock:(BOOL)unblock
194 //We want to block on all accounts with the same service class. If you want someone gone, you want 'em GONE.
195 NSEnumerator *enumerator = [[[adium accountController] accountsWithServiceClassOfService:[contact service]] objectEnumerator];
196 AIAccount *account = nil;
198 while((account = [enumerator nextObject])){
199 if([account conformsToProtocol:@protocol(AIAccount_Privacy)]){
200 AIAccount <AIAccount_Privacy> *privacyAccount = (AIAccount <AIAccount_Privacy> *)account;
202 if([[privacyAccount listObjectIDsOnPrivacyList:PRIVACY_DENY] containsObject:[contact UID]]){
203 [privacyAccount removeListObject:contact fromPrivacyList:PRIVACY_DENY];
206 if(![[privacyAccount listObjectIDsOnPrivacyList:PRIVACY_DENY] containsObject:[contact UID]]){
207 [privacyAccount addListObject:contact toPrivacyList:PRIVACY_DENY];
214 - (BOOL)_searchPrivacyListsForListContact:(AIListContact *)contact withDesiredResult:(BOOL)desiredResult
216 AIAccount *account = nil;
217 NSEnumerator *enumerator;
219 enumerator = [[[adium accountController] accountsWithServiceClassOfService:[contact service]] objectEnumerator];
221 while((account = [enumerator nextObject])){
222 if([account conformsToProtocol:@protocol(AIAccount_Privacy)]){
223 AIAccount <AIAccount_Privacy> *privacyAccount = (AIAccount <AIAccount_Privacy> *)account;
224 if([[privacyAccount listObjectIDsOnPrivacyList:PRIVACY_DENY] containsObject:[contact UID]] == desiredResult){