adium 4105:831ee75de731: Added support for Blocking/Unblocking a...
commits at adium.im
commits at adium.im
Tue Aug 2 19:13:07 UTC 2011
details: http://hg.adium.im/adium/rev/831ee75de731
revision: 4105:831ee75de731
branch: (none)
author: Adrian Godoroja <robotive at me.com>
date: Tue Aug 02 22:12:47 2011 +0300
Added support for Blocking/Unblocking all contacts in a group.
Patch by squid890, r=robotive. Refs #2177.
diffs (254 lines):
diff -r fef580659bb5 -r 831ee75de731 ChangeLogs/Changes.txt
--- a/ChangeLogs/Changes.txt Tue Aug 02 20:31:11 2011 +0300
+++ b/ChangeLogs/Changes.txt Tue Aug 02 22:12:47 2011 +0300
@@ -22,6 +22,7 @@
* "User Picture Change" menu now looks native on Leopard and newer systems. (#11964)
* "User Picture" - image well, supports drag and drop
* Fixed positioning of selected icon in Recent Icons not being reapplied when icon is reselected. (#9908)
+ * Added support for Blocking/Unblocking all contacts in a group. (#2177)
Dock icon
* Moved the dock badge to the top right to be consistent with other Mac OS X applications such as Mail. (#13439)
diff -r fef580659bb5 -r 831ee75de731 Source/ESBlockingPlugin.m
--- a/Source/ESBlockingPlugin.m Tue Aug 02 20:31:11 2011 +0300
+++ b/Source/ESBlockingPlugin.m Tue Aug 02 22:12:47 2011 +0300
@@ -27,6 +27,7 @@
#import <AIUtilities/AIImageAdditions.h>
#import <Adium/AIAccount.h>
#import <Adium/AIListContact.h>
+#import <Adium/AIListGroup.h>
#import <Adium/AIMetaContact.h>
#import <Adium/AIChat.h>
@@ -34,6 +35,10 @@
#define UNBLOCK AILocalizedString(@"Unblock","Unblock Contact menu item")
#define BLOCK_MENUITEM [BLOCK stringByAppendingEllipsis]
#define UNBLOCK_MENUITEM [UNBLOCK stringByAppendingEllipsis]
+#define BLOCK_GROUP AILocalizedString(@"Block Group","Block Group menu item")
+#define UNBLOCK_GROUP AILocalizedString(@"Unblock Group","Unblock Group menu item")
+#define BLOCK_GROUP_MENUITEM [BLOCK_GROUP stringByAppendingEllipsis]
+#define UNBLOCK_GROUP_MENUITEM [UNBLOCK_GROUP stringByAppendingEllipsis]
#define TOOLBAR_ITEM_IDENTIFIER @"BlockParticipants"
#define TOOLBAR_BLOCK_ICON_KEY @"Block"
#define TOOLBAR_UNBLOCK_ICON_KEY @"Unblock"
@@ -44,6 +49,9 @@
- (BOOL)areAllGivenContactsBlocked:(NSArray *)contacts;
- (void)setPrivacy:(BOOL)block forContacts:(NSArray *)contacts;
- (IBAction)blockOrUnblockParticipants:(NSToolbarItem *)senderItem;
+- (BOOL)blockContactInGroup:(AIListContact *)contact withBlock:(BOOL)isBlock;
+- (BOOL)contactIsBlocked:(AIListContact *)chkContact;
+
//protocols
- (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent;
@@ -152,12 +160,36 @@
adium.interfaceController.selectedListObject :
adium.menuController.currentContextMenuObject);
- //Don't do groups
+ //Handles group block
+ if ([object isKindOfClass:[AIListGroup class]]) {
+ BOOL shouldBlock;
+ NSString *format;
+ AIListGroup *group = (AIListGroup *)object;
+ shouldBlock = [[sender title] isEqualToString:BLOCK_GROUP_MENUITEM];
+ format = (shouldBlock ?
+ AILocalizedString(@"Are you sure you want to block all contacts in the group %@?",nil) :
+ AILocalizedString(@"Are you sure you want to unblock all contacts in the group %@?",nil));
+
+ if (NSRunAlertPanel([NSString stringWithFormat:format, [group displayName]],
+ @"",
+ (shouldBlock ? BLOCK_GROUP : UNBLOCK_GROUP),
+ AILocalizedString(@"Cancel", nil),
+ nil) == NSAlertDefaultReturn) {
+
+ //iterate over all contacts in the group
+ AIListContact *curContact = nil;
+ for (curContact in [group uniqueContainedObjects]) {
+ [self blockContactInGroup:curContact withBlock:shouldBlock];
+ }
+ }
+ }
+
+ //Handle single contact group
if ([object isKindOfClass:[AIListContact class]]) {
AIListContact *contact = (AIListContact *)object;
BOOL shouldBlock;
NSString *format;
-
+
shouldBlock = [[sender title] isEqualToString:BLOCK_MENUITEM];
format = (shouldBlock ?
AILocalizedString(@"Are you sure you want to block %@?",nil) :
@@ -225,7 +257,39 @@
object = adium.menuController.currentContextMenuObject;
}
- //Don't do groups
+ // For handling groups
+ if ([object isKindOfClass:[AIListGroup class]]) {
+ AIListGroup *group = (AIListGroup *)object;
+
+ //iterate over contacts in group
+ NSInteger numContactsBlocked = 0;
+ NSInteger numContactsUnblocked = 0;
+ AIListContact *curContact = nil;
+
+ for (curContact in [group uniqueContainedObjects]) {
+ if ([self contactIsBlocked:curContact]) {
+ numContactsBlocked++;
+ } else {
+ numContactsUnblocked++;
+ }
+ }
+
+ if (numContactsBlocked || numContactsUnblocked) {
+ // if there are more blocked in the group, menu says "Unblock..."
+ if (numContactsBlocked > numContactsUnblocked) {
+ [menuItem setTitle:UNBLOCK_GROUP_MENUITEM];
+ } else {
+ [menuItem setTitle:BLOCK_GROUP_MENUITEM];
+ }
+
+ return YES;
+ } else {
+ return NO;
+ }
+
+ }
+
+ // For handling contacts
if ([object isKindOfClass:[AIListContact class]]) {
//Handle metas
if ([object isKindOfClass:[AIMetaContact class]]) {
@@ -381,6 +445,130 @@
}
/*!
+ * @brief Used in conjunction with blocking a group, to block every contact in that group
+ *
+ * @param contact The contact to block
+ * @result A flag indicating if the block was succesful
+ */
+- (BOOL)blockContactInGroup:(AIListContact *)contact withBlock:(BOOL)isBlock
+{
+ //Handle metas
+ if ([contact isKindOfClass:[AIMetaContact class]]) {
+ AIMetaContact *meta = (AIMetaContact *)contact;
+
+ //Enumerate over the various list contacts contained
+ AIListContact *containedContact = nil;
+
+ for (containedContact in [meta uniqueContainedObjects]) {
+ AIAccount *acct = containedContact.account;
+ if ([acct conformsToProtocol:@protocol(AIAccount_Privacy)]) {
+ [self _setContact:containedContact isBlocked:isBlock];
+ } else {
+ NSLog(@"Account %@ does not support blocking (contact %@ not blocked on this account)", acct, containedContact);
+ }
+ }
+ } else {
+ AIAccount *acct = contact.account;
+ if ([acct conformsToProtocol:@protocol(AIAccount_Privacy)]) {
+ [self _setContact:contact isBlocked:isBlock];
+ } else {
+ NSLog(@"Account %@ does not support blocking (contact %@ not blocked on this account)", acct, contact);
+ }
+ }
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"AIPrivacySettingsChangedOutsideOfPrivacyWindow"
+ object:nil];
+
+ return YES;
+}
+
+/*!
+ * @brief Checks if a contact is blocked, used in conjunction with group blocking
+ *
+ * @param contact The contact to check
+ * @result A flag indicating if the contact is blocked
+ */
+- (BOOL)contactIsBlocked:(AIListContact *)chkContact
+{
+ //Handle metas
+ if ([chkContact isKindOfClass:[AIMetaContact class]]) {
+ AIMetaContact *meta = (AIMetaContact *)chkContact;
+
+ //Enumerate over the various list contacts contained
+ AIListContact *contact = nil;
+ NSInteger votesForBlocked = 0;
+ NSInteger votesForUnblocked = 0;
+
+ for (contact in [meta uniqueContainedObjects]) {
+ AIAccount *acct = contact.account;
+ if ([acct conformsToProtocol:@protocol(AIAccount_Privacy)]) {
+ AIPrivacyType privType = (([(AIAccount <AIAccount_Privacy> *)acct privacyOptions] == AIPrivacyOptionAllowUsers) ? AIPrivacyTypePermit : AIPrivacyTypeDeny);
+ if ([[(AIAccount <AIAccount_Privacy> *)acct listObjectsOnPrivacyList:privType] containsObject:contact]) {
+ switch (privType) {
+ case AIPrivacyTypePermit:
+ /* He's on a permit list. The action would remove him, blocking him */
+ votesForUnblocked++;
+ break;
+ case AIPrivacyTypeDeny:
+ /* He's on a deny list. The action would remove him, unblocking him */
+ votesForBlocked++;
+ break;
+ }
+
+ } else {
+ switch (privType) {
+ case AIPrivacyTypePermit:
+ /* He's not on the permit list. The action would add him, unblocking him */
+ votesForBlocked++;
+ break;
+ case AIPrivacyTypeDeny:
+ /* He's not on a deny list. The action would add him, blocking him */
+ votesForUnblocked++;
+ break;
+ }
+ }
+ }
+ }
+
+ if (votesForBlocked) {
+ return YES;
+ } else {
+ return NO;
+ }
+
+ } else {
+ AIListContact *contact = (AIListContact *)chkContact;
+ AIAccount *acct = chkContact.account;
+ if ([acct conformsToProtocol:@protocol(AIAccount_Privacy)]) {
+ AIPrivacyType privType = (([(AIAccount <AIAccount_Privacy> *)acct privacyOptions] == AIPrivacyOptionAllowUsers) ? AIPrivacyTypePermit : AIPrivacyTypeDeny);
+ if ([[(AIAccount <AIAccount_Privacy> *)acct listObjectsOnPrivacyList:privType] containsObject:contact]) {
+ switch (privType) {
+ case AIPrivacyTypePermit:
+ // He's on a permit list, therefore he is not blocked
+ return NO;
+ case AIPrivacyTypeDeny:
+ // He's on a deny list, therefore he is blocked
+ return YES;
+ }
+
+ } else {
+ switch (privType) {
+ case AIPrivacyTypePermit:
+ // He's not on the permit list, therefore he is blocked
+ return YES;
+ case AIPrivacyTypeDeny:
+ // He's not on a deny list, therefore he is unblocked
+ return NO;
+ }
+ }
+
+ return NO;
+ }
+ }
+
+ return NO;
+}
+
+/*!
* @brief Determine if all the referenced contacts are blocked or unblocked
*
* @param contacts The contacts to query
More information about the commits
mailing list