Better contact views

This commit is contained in:
Yann Diorcet 2012-07-15 19:55:15 +02:00
parent 4e2302fa08
commit 2b268d8603
4 changed files with 140 additions and 151 deletions

View file

@ -27,26 +27,17 @@
@interface ContactDetailsTableViewController : UITableViewController<UIModalViewDelegate, UITextFieldDelegate> {
@private
ABRecordRef contact;
ABRecordID contactID;
NSMutableArray *dataCache;
ABAddressBookRef addressBook;
ContactDetailsLabelViewController *contactDetailsLabelViewController;
NSMutableArray *labelArray;
NSIndexPath *editingIndexPath;
BOOL inhibUpdate;
@public
UIContactDetailsHeader *headerController;
UIContactDetailsFooter *footerController;
}
@property (nonatomic, assign) ABRecordID contactID;
@property (nonatomic, assign) ABRecordRef contact;
- (void)newContact;
- (void)removeContact;
- (void)addSipField:(NSString*)address;
- (void)loadData;
- (void)saveData;
- (void)resetData;
@end

View file

@ -23,6 +23,7 @@
#import "UIView+ModalStack.h"
#import "UACellBackgroundView.h"
#import "UILinphone.h"
#import "OrderedDictionary.h"
@interface Entry : NSObject
@ -53,8 +54,7 @@
@implementation ContactDetailsTableViewController
@synthesize contactID;
@synthesize contact;
#pragma mark - Lifecycle Functions
@ -65,15 +65,9 @@
@"Linphone",
[NSString stringWithString:(NSString*)kABPersonPhoneMobileLabel],
[NSString stringWithString:(NSString*)kABPersonPhoneIPhoneLabel],
[NSString stringWithString:(NSString*)kABPersonPhoneMainLabel],
[NSString stringWithString:(NSString*)kABPersonPhoneHomeFAXLabel],
[NSString stringWithString:(NSString*)kABPersonPhoneWorkFAXLabel], nil];
inhibUpdate = FALSE;
[NSString stringWithString:(NSString*)kABPersonPhoneMainLabel], nil];
headerController = [[UIContactDetailsHeader alloc] init];
footerController = [[UIContactDetailsFooter alloc] init];
addressBook = ABAddressBookCreate();
ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, self);
}
- (id)init {
@ -92,10 +86,7 @@
return self;
}
- (void)dealloc {
ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self);
CFRelease(addressBook);
- (void)dealloc {
[labelArray release];
[dataCache release];
[headerController release];
@ -159,90 +150,13 @@
}
- (NSDictionary*)getLocalizedLabels {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:[labelArray count]];
OrderedDictionary *dict = [[OrderedDictionary alloc] initWithCapacity:[labelArray count]];
for(NSString *str in labelArray) {
[dict setObject:[ContactDetailsTableViewController localizeLabel:str] forKey:str];
}
return [dict autorelease];
}
static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
ContactDetailsTableViewController* controller = (ContactDetailsTableViewController*)context;
//ABAddressBookRevert(addressBook);
if(!controller->inhibUpdate && ![controller isEditing]) {
[controller resetData];
}
}
- (void)resetData {
if(contact == NULL)
return;
NSLog(@"Reset data to contact %p", contact);
ABAddressBookRevert(addressBook);
contact = ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(contact));
if(contact == NULL) {
[[footerController removeButton] sendActionsForControlEvents: UIControlEventTouchUpInside];
return;
}
[self loadData];
}
- (void)removeContact {
if(contact == NULL)
return;
// Remove contact from book
if(ABRecordGetRecordID(contact) != kABRecordInvalidID) {
NSError* error = NULL;
ABAddressBookRemoveRecord(addressBook, contact, (CFErrorRef*)&error);
if (error != NULL) {
NSLog(@"Remove contact %p: Fail(%@)", contact, [error localizedDescription]);
} else {
NSLog(@"Remove contact %p: Success!", contact);
}
contact = NULL;
// Save address book
error = NULL;
inhibUpdate = TRUE;
ABAddressBookSave(addressBook, (CFErrorRef*)&error);
inhibUpdate = FALSE;
if (error != NULL) {
NSLog(@"Save AddressBook: Fail(%@)", [error localizedDescription]);
} else {
NSLog(@"Save AddressBook: Success!");
}
}
}
- (void)saveData {
if(contact == NULL)
return;
// Add contact to book
NSError* error = NULL;
if(ABRecordGetRecordID(contact) == kABRecordInvalidID) {
ABAddressBookAddRecord(addressBook, contact, (CFErrorRef*)&error);
if (error != NULL) {
NSLog(@"Add contact %p: Fail(%@)", contact, [error localizedDescription]);
} else {
NSLog(@"Add contact %p: Success!", contact);
}
}
// Save address book
error = NULL;
inhibUpdate = TRUE;
ABAddressBookSave(addressBook, (CFErrorRef*)&error);
inhibUpdate = FALSE;
if (error != NULL) {
NSLog(@"Save AddressBook: Fail(%@)", [error localizedDescription]);
} else {
NSLog(@"Save AddressBook: Success!");
}
}
- (void)loadData {
[dataCache removeAllObjects];
@ -341,10 +255,12 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
CFRelease(lMap);
}
NSArray *tagInsertIndexPath = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:count inSection:section]];
if (animated) {
[tableview insertRowsAtIndexPaths:tagInsertIndexPath withRowAnimation:UITableViewRowAnimationFade];
// Update accessory
if (count > 0) {
[tableview reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:count -1 inSection:section]] withRowAnimation:FALSE];
}
[tableview insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:count inSection:section]] withRowAnimation:UITableViewRowAnimationFade];
}
}
@ -405,14 +321,8 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
#pragma mark - Property Functions
- (void)setContactID:(ABRecordID)acontactID {
self->contactID = acontactID;
contact = ABAddressBookGetPersonWithRecordID(addressBook, contactID);
[self loadData];
}
- (void)newContact {
contact = ABPersonCreate();
- (void)setContact:(ABRecordRef)acontact {
self->contact = acontact;
[self loadData];
}
@ -561,7 +471,6 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
if (editingStyle == UITableViewCellEditingStyleInsert) {
[self.tableView beginUpdates];
[self addEntry:self.tableView section:[indexPath section] animated:TRUE];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:FALSE];
[self.tableView endUpdates];
} else if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.tableView beginUpdates];
@ -666,28 +575,30 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
- (void)modalViewDismiss:(UIModalViewController*)controller value:(id)value {
[[[self view]superview] removeModalView:[contactDetailsLabelViewController view]];
contactDetailsLabelViewController = nil;
NSMutableArray *sectionDict = [dataCache objectAtIndex:[editingIndexPath section]];
Entry *entry = [sectionDict objectAtIndex:[editingIndexPath row]];
if([editingIndexPath section] == 0) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceLabelAtIndex(lMap, (CFStringRef)((NSString*)value), index);
ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, nil);
CFRelease(lMap);
} else if([editingIndexPath section] == 1) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceLabelAtIndex(lMap, (CFStringRef)((NSString*)value), index);
ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, nil);
CFRelease(lMap);
if(value != nil) {
NSMutableArray *sectionDict = [dataCache objectAtIndex:[editingIndexPath section]];
Entry *entry = [sectionDict objectAtIndex:[editingIndexPath row]];
if([editingIndexPath section] == 0) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceLabelAtIndex(lMap, (CFStringRef)((NSString*)value), index);
ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, nil);
CFRelease(lMap);
} else if([editingIndexPath section] == 1) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceLabelAtIndex(lMap, (CFStringRef)((NSString*)value), index);
ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, nil);
CFRelease(lMap);
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject: editingIndexPath] withRowAnimation:FALSE];
[self.tableView endUpdates];
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject: editingIndexPath] withRowAnimation:FALSE];
[self.tableView endUpdates];
[editingIndexPath release];
editingIndexPath = nil;
}

View file

@ -30,6 +30,9 @@
UIToggleButton *editButton;
UIButton *backButton;
UIButton *cancelButton;
ABAddressBookRef addressBook;
BOOL inhibUpdate;
}
@property (nonatomic, assign) ABRecordRef contact;

View file

@ -33,11 +33,17 @@
- (id)init {
self = [super initWithNibName:@"ContactDetailsViewController" bundle:[NSBundle mainBundle]];
if(self != nil) {
inhibUpdate = FALSE;
addressBook = ABAddressBookCreate();
ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, self);
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self);
CFRelease(addressBook);
[tableController release];
[editButton release];
@ -50,39 +56,120 @@
#pragma mark -
- (void)resetData {
NSLog(@"Reset data to contact %p", contact);
ABRecordID recordID = ABRecordGetRecordID(contact);
ABAddressBookRevert(addressBook);
contact = ABAddressBookGetPersonWithRecordID(addressBook, recordID);
if(contact == NULL) {
[[PhoneMainView instance] popView];
return;
}
[tableController setContact:contact];
}
static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
ContactDetailsViewController* controller = (ContactDetailsViewController*)context;
if(!controller->inhibUpdate && ![[controller tableController] isEditing]) {
[controller resetData];
}
}
- (void)removeContact {
if(contact == NULL) {
[[PhoneMainView instance] popView];
return;
}
// Remove contact from book
if(ABRecordGetRecordID(contact) != kABRecordInvalidID) {
NSError* error = NULL;
ABAddressBookRemoveRecord(addressBook, contact, (CFErrorRef*)&error);
if (error != NULL) {
NSLog(@"Remove contact %p: Fail(%@)", contact, [error localizedDescription]);
} else {
NSLog(@"Remove contact %p: Success!", contact);
}
contact = NULL;
// Save address book
error = NULL;
inhibUpdate = TRUE;
ABAddressBookSave(addressBook, (CFErrorRef*)&error);
inhibUpdate = FALSE;
if (error != NULL) {
NSLog(@"Save AddressBook: Fail(%@)", [error localizedDescription]);
} else {
NSLog(@"Save AddressBook: Success!");
}
}
}
- (void)saveData {
if(contact == NULL) {
[[PhoneMainView instance] popView];
return;
}
// Add contact to book
NSError* error = NULL;
if(ABRecordGetRecordID(contact) == kABRecordInvalidID) {
ABAddressBookAddRecord(addressBook, contact, (CFErrorRef*)&error);
if (error != NULL) {
NSLog(@"Add contact %p: Fail(%@)", contact, [error localizedDescription]);
} else {
NSLog(@"Add contact %p: Success!", contact);
}
}
// Save address book
error = NULL;
inhibUpdate = TRUE;
ABAddressBookSave(addressBook, (CFErrorRef*)&error);
inhibUpdate = FALSE;
if (error != NULL) {
NSLog(@"Save AddressBook: Fail(%@)", [error localizedDescription]);
} else {
NSLog(@"Save AddressBook: Success!");
}
}
- (void)newContact {
[tableController newContact];
self->contact = ABPersonCreate();
[tableController setContact:self->contact];
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
}
- (void)newContact:(NSString*)address {
[tableController newContact];
self->contact = ABPersonCreate();
[tableController setContact:self->contact];
[tableController addSipField:address];
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
}
- (void)editContact:(ABRecordRef)acontact {
self->contact = acontact;
[tableController setContactID:ABRecordGetRecordID(acontact)];
self->contact = ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact));
[tableController setContact:self->contact];
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
}
- (void)editContact:(ABRecordRef)acontact address:(NSString*)address {
self->contact = acontact;
[tableController setContactID:ABRecordGetRecordID(acontact)];
self->contact = ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact));
[tableController setContact:self->contact];
[tableController addSipField:address];
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
}
#pragma mark - Property Functions
- (void)setContact:(ABRecordRef)acontact {
self->contact = acontact;
[tableController setContactID:ABRecordGetRecordID(acontact)];
self->contact = ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact));
[tableController setContact:self->contact];
[self disableEdit:FALSE];
}
@ -115,7 +202,7 @@
[tableController viewWillDisappear:NO];
}
[self disableEdit:FALSE];
[tableController resetData];
[self resetData];
}
- (void)viewWillAppear:(BOOL)animated {
@ -175,11 +262,8 @@
#pragma mark - Action Functions
- (IBAction)onCancelClick:(id)event {
[self disableEdit:FALSE];
[tableController resetData];
if([tableController contactID] == kABRecordInvalidID) {
[[PhoneMainView instance] popView];
}
[self disableEdit:TRUE];
[self resetData];
}
- (IBAction)onBackClick:(id)event {
@ -189,7 +273,7 @@
- (IBAction)onEditClick:(id)event {
if([tableController isEditing]) {
[self disableEdit:TRUE];
[tableController saveData];
[self saveData];
} else {
[self enableEdit:TRUE];
}
@ -197,7 +281,7 @@
- (void)onRemove:(id)event {
[self disableEdit:FALSE];
[tableController removeContact];
[self removeContact];
[[PhoneMainView instance] popView];
}