diff --git a/Classes/ContactDetailsTableViewController.h b/Classes/ContactDetailsTableViewController.h index 7ec5903b4..e05883262 100644 --- a/Classes/ContactDetailsTableViewController.h +++ b/Classes/ContactDetailsTableViewController.h @@ -27,26 +27,17 @@ @interface ContactDetailsTableViewController : UITableViewController { @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 diff --git a/Classes/ContactDetailsTableViewController.m b/Classes/ContactDetailsTableViewController.m index 085714ea5..fc3b18528 100644 --- a/Classes/ContactDetailsTableViewController.m +++ b/Classes/ContactDetailsTableViewController.m @@ -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; } diff --git a/Classes/ContactDetailsViewController.h b/Classes/ContactDetailsViewController.h index 5f4a8e454..16e96f59e 100644 --- a/Classes/ContactDetailsViewController.h +++ b/Classes/ContactDetailsViewController.h @@ -30,6 +30,9 @@ UIToggleButton *editButton; UIButton *backButton; UIButton *cancelButton; + + ABAddressBookRef addressBook; + BOOL inhibUpdate; } @property (nonatomic, assign) ABRecordRef contact; diff --git a/Classes/ContactDetailsViewController.m b/Classes/ContactDetailsViewController.m index 1b9228faf..21afc824c 100644 --- a/Classes/ContactDetailsViewController.m +++ b/Classes/ContactDetailsViewController.m @@ -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]; }