VoiceMac/Classes/VoiceBase/AddressBook/MGMAddressBook.m
GRMrGecko 62734d7fef Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-09-23 22:02:03 -05:00

265 lines
10 KiB
Objective-C

//
// MGMAddressBook.m
// VoiceBase
//
// Created by Mr. Gecko on 8/17/10.
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
#import "MGMAddressBook.h"
#import "MGMContactsProtocol.h"
#import "MGMAddons.h"
#if TARGET_OS_IPHONE
#import <AddressBook/ABAddressBook.h>
#import <AddressBook/ABPerson.h>
#import <AddressBook/ABGroup.h>
#import <AddressBook/ABMultiValue.h>
#else
#import <AddressBook/AddressBook.h>
#endif
@implementation MGMAddressBook
- (id)initWithDelegate:(id)theDelegate {
if ((self = [super init])) {
delegate = theDelegate;
shouldStop = NO;
gettingContacts = NO;
gettingGroups = NO;
#if TARGET_OS_IPHONE
addressBook = ABAddressBookCreate();
#else
addressBook = [[ABAddressBook sharedAddressBook] retain];
#endif
}
return self;
}
- (void)dealloc {
#if TARGET_OS_IPHONE
if (addressBook!=NULL)
CFRelease(addressBook);
#else
[addressBook release];
#endif
[super dealloc];
}
#if !TARGET_OS_IPHONE
+ (NSData *)userPhotoData {
return [[[ABAddressBook sharedAddressBook] me] imageData];
}
#endif
- (void)stop {
shouldStop = YES;
while (gettingContacts)
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
while (gettingGroups)
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
shouldStop = NO;
}
- (void)getContacts:(id)sender {
if (gettingContacts) {
NSDictionary *info = [NSDictionary dictionaryWithObject:contactsSender forKey:MGMCRecallSender];
NSError *error = [NSError errorWithDomain:MGMCRecallError code:1 userInfo:info];
if ([sender respondsToSelector:@selector(contactsError:)]) [sender contactsError:error];
return;
}
gettingContacts = YES;
contactsSender = sender;
[NSThread detachNewThreadSelector:@selector(contactsBackground) toTarget:self withObject:nil];
}
- (void)contactsBackground {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
#if TARGET_OS_IPHONE
NSArray *people = [(NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook) autorelease];
for (unsigned int i=0; i<[people count]; i++) {
if (shouldStop) break;
ABRecordRef person = [people objectAtIndex:i];
NSString *name = @"";
NSString *firstName = [(NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty) autorelease];
if (firstName!=nil)
name = firstName;
NSString *lastName = [(NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty) autorelease];
if ([name isEqualToString:@""] && lastName!=nil)
name = lastName;
else if (lastName!=nil)
name = [name stringByAppendingFormat:@" %@", lastName];
NSString *company = [(NSString *)ABRecordCopyValue(person, kABPersonOrganizationProperty) autorelease];
if (company==nil)
company = @"";
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
int phonesCount = ABMultiValueGetCount(phones);
NSData *image = [(NSData *)ABPersonCopyImageData(person) autorelease];
if (phonesCount>0) {
if (image!=nil)
image = [image resizeTo:MGMABPhotoSize];
}
for (int p=0; p<phonesCount; p++) {
if (shouldStop) break;
NSMutableDictionary *contact = [NSMutableDictionary dictionary];
[contact setObject:name forKey:MGMCName];
[contact setObject:company forKey:MGMCCompany];
CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(phones, p);
if (delegate!=nil)
[contact setObject:[(NSString *)phoneNumber phoneFormatWithAreaCode:[delegate areaCode]] forKey:MGMCNumber];
else
[contact setObject:[(NSString *)phoneNumber phoneFormat] forKey:MGMCNumber];
CFRelease(phoneNumber);
NSString *label = [(NSString *)ABMultiValueCopyLabelAtIndex(phones, p) autorelease];
NSRange range = [label rangeOfString:@"<"];
if (range.location!=NSNotFound) {
NSString *string = [label substringFromIndex:range.location+range.length];
range = [string rangeOfString:@">"];
if (range.location==NSNotFound) {
NSLog(@"failed 0007");
} else {
label = [string substringWithRange:NSMakeRange(0, range.location)];
}
}
[contact setObject:[label capitalizedString] forKey:MGMCLabel];
if (image!=nil)
[contact setObject:image forKey:MGMCPhoto];
if ([contactsSender respondsToSelector:@selector(gotContact:)]) [contactsSender gotContact:contact];
}
CFRelease(phones);
}
#else
NSArray *people = [addressBook people];
for (unsigned int i=0; i<[people count]; i++) {
if (shouldStop) break;
ABPerson *person = [people objectAtIndex:i];
if ([person valueForProperty:kABPhoneProperty]!=nil) {
NSString *name = @"";
if ([person valueForProperty:kABFirstNameProperty])
name = [person valueForProperty:kABFirstNameProperty];
if ([name isEqualToString:@""] && [person valueForProperty:kABLastNameProperty]!=nil)
name = [person valueForProperty:kABLastNameProperty];
else if ([person valueForProperty:kABLastNameProperty]!=nil)
name = [name stringByAppendingFormat:@" %@", [person valueForProperty:kABLastNameProperty]];
NSString *company = @"";
if ([person valueForProperty:kABOrganizationProperty]!=nil)
company = [person valueForProperty:kABOrganizationProperty];
ABMultiValue *phones = [person valueForProperty:kABPhoneProperty];
NSData *image = [person imageData];
if ([phones count]>0) {
if (image!=nil)
image = [image resizeTo:MGMABPhotoSize];
}
for (int p=0; p<[phones count]; p++) {
if (shouldStop) break;
NSMutableDictionary *contact = [NSMutableDictionary dictionary];
[contact setObject:name forKey:MGMCName];
[contact setObject:company forKey:MGMCCompany];
if (delegate!=nil)
[contact setObject:[[phones valueAtIndex:p] phoneFormatWithAreaCode:[delegate areaCode]] forKey:MGMCNumber];
else
[contact setObject:[[phones valueAtIndex:p] phoneFormat] forKey:MGMCNumber];
NSString *label = [phones labelAtIndex:p];
NSRange range = [label rangeOfString:@"<"];
if (range.location!=NSNotFound) {
NSString *string = [label substringFromIndex:range.location+range.length];
range = [string rangeOfString:@">"];
if (range.location==NSNotFound) {
NSLog(@"failed 0007");
} else {
label = [string substringWithRange:NSMakeRange(0, range.location)];
}
}
[contact setObject:[label capitalizedString] forKey:MGMCLabel];
if (image!=nil)
[contact setObject:image forKey:MGMCPhoto];
if ([contactsSender respondsToSelector:@selector(gotContact:)]) [contactsSender gotContact:contact];
}
}
}
#endif
if (!shouldStop)
if ([contactsSender respondsToSelector:@selector(doneGettingContacts)]) [contactsSender doneGettingContacts];
gettingContacts = NO;
[pool drain];
}
- (void)getGroups:(id)sender {
if (gettingGroups) {
NSDictionary *info = [NSDictionary dictionaryWithObject:groupsSender forKey:MGMCRecallSender];
NSError *error = [NSError errorWithDomain:MGMCRecallError code:1 userInfo:info];
if ([sender respondsToSelector:@selector(groupsError:)]) [sender groupsError:error];
return;
}
gettingGroups = YES;
groupsSender = sender;
[NSThread detachNewThreadSelector:@selector(groupsBackground:) toTarget:self withObject:sender];
}
- (void)groupsBackground:(id<MGMContactsDelegate>)sender {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
#if TARGET_OS_IPHONE
NSArray *abGroups = [(NSArray *)ABAddressBookCopyArrayOfAllGroups(addressBook) autorelease];
for (unsigned int i=0; i<[abGroups count]; i++) {
if (shouldStop) break;
ABRecordRef abGroup = [abGroups objectAtIndex:i];
NSString *name = [(NSString *)ABRecordCopyValue(abGroup, kABGroupNameProperty) autorelease];
NSArray *people = [(NSArray *)ABGroupCopyArrayOfAllMembers(abGroup) autorelease];
NSMutableArray *groupMembers = [NSMutableArray array];
for (unsigned int m=0; m<[people count]; m++) {
if (shouldStop) break;
ABRecordRef person = [people objectAtIndex:m];
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
if (phones!=NULL) {
if (shouldStop) break;
int phonesCount = ABMultiValueGetCount(phones);
for (int p=0; p<phonesCount; p++) {
if (delegate!=nil)
[groupMembers addObject:[[(NSString *)ABMultiValueCopyValueAtIndex(phones, p) autorelease] phoneFormatWithAreaCode:[delegate areaCode]]];
else
[groupMembers addObject:[[(NSString *)ABMultiValueCopyValueAtIndex(phones, p) autorelease] phoneFormat]];
}
CFRelease(phones);
}
}
if (!shouldStop)
if ([groupsSender respondsToSelector:@selector(gotGroup:withMembers:)]) [groupsSender gotGroup:name withMembers:groupMembers];
}
#else
NSArray *abGroups = [addressBook groups];
for (unsigned int i=0; i<[abGroups count]; i++) {
if (shouldStop) break;
ABGroup *abGroup = [abGroups objectAtIndex:i];
NSString *name = [abGroup valueForProperty:kABGroupNameProperty];
NSArray *people = [abGroup members];
NSMutableArray *groupMembers = [NSMutableArray array];
for (unsigned int m=0; m<[people count]; m++) {
if (shouldStop) break;
ABPerson *person = [people objectAtIndex:m];
if ([person valueForProperty:kABPhoneProperty]!=nil) {
ABMultiValue *phones = [person valueForProperty:kABPhoneProperty];
for (int p=0; p<[phones count]; p++) {
if (shouldStop) break;
if (delegate!=nil)
[groupMembers addObject:[[phones valueAtIndex:p] phoneFormatWithAreaCode:[delegate areaCode]]];
else
[groupMembers addObject:[[phones valueAtIndex:p] phoneFormat]];
}
}
}
if (!shouldStop)
if ([groupsSender respondsToSelector:@selector(gotGroup:withMembers:)]) [groupsSender gotGroup:name withMembers:groupMembers];
}
#endif
if (!shouldStop)
if ([groupsSender respondsToSelector:@selector(doneGettingGroups)]) [groupsSender doneGettingGroups];
gettingGroups = NO;
[pool drain];
}
@end