diff --git a/Classes/ContactDetailsTableView.h b/Classes/ContactDetailsTableView.h index 72777fc20..1170f5d93 100644 --- a/Classes/ContactDetailsTableView.h +++ b/Classes/ContactDetailsTableView.h @@ -24,8 +24,8 @@ typedef enum _ContactSections { ContactSections_None = 0, // first section is empty because we cannot set header for first section - ContactSections_First_Name, - ContactSections_Last_Name, + ContactSections_FirstName, + ContactSections_LastName, ContactSections_Sip, ContactSections_Number, ContactSections_Email, @@ -36,7 +36,6 @@ typedef enum _ContactSections { @private NSMutableArray *dataCache; NSMutableArray *labelArray; - NSIndexPath *editingIndexPath; } @property(nonatomic, assign, setter=setContact:) ABRecordRef contact; diff --git a/Classes/ContactDetailsTableView.m b/Classes/ContactDetailsTableView.m index d50c6f6e1..8c99bc6d3 100644 --- a/Classes/ContactDetailsTableView.m +++ b/Classes/ContactDetailsTableView.m @@ -53,7 +53,7 @@ #pragma mark - Lifecycle Functions -- (void)initContactDetailsTableViewController { +INIT_WITH_COMMON_C { dataCache = [[NSMutableArray alloc] init]; // pre-fill the data-cache with empty arrays @@ -66,22 +66,6 @@ [NSString stringWithString:(NSString *)kABPersonPhoneMobileLabel], [NSString stringWithString:(NSString *)kABPersonPhoneIPhoneLabel], [NSString stringWithString:(NSString *)kABPersonPhoneMainLabel], nil]; - editingIndexPath = nil; -} - -- (id)init { - self = [super init]; - if (self) { - [self initContactDetailsTableViewController]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - [self initContactDetailsTableViewController]; - } return self; } @@ -93,10 +77,6 @@ #pragma mark - -- (void)updateModification { - [contactDetailsDelegate onModification:nil]; -} - - (NSMutableArray *)getSectionData:(NSInteger)section { if (section == ContactSections_Number) { return [dataCache objectAtIndex:0]; @@ -114,9 +94,9 @@ - (ABPropertyID)propertyIDForSection:(ContactSections)section { switch (section) { - case ContactSections_First_Name: + case ContactSections_FirstName: return kABPersonFirstNameProperty; - case ContactSections_Last_Name: + case ContactSections_LastName: return kABPersonLastNameProperty; case ContactSections_Sip: return kABPersonInstantMessageProperty; @@ -482,7 +462,7 @@ } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - if (section == ContactSections_First_Name || section == ContactSections_Last_Name) { + if (section == ContactSections_FirstName || section == ContactSections_LastName) { return (self.tableView.isEditing) ? 1 : 0 /*no first and last name when not editting */; } else { return [[self getSectionData:section] count]; @@ -496,19 +476,20 @@ cell = [[UIContactDetailsCell alloc] initWithIdentifier:kCellId]; [cell.editTextfield setDelegate:self]; } + cell.indexPath = indexPath; NSMutableArray *sectionDict = [self getSectionData:[indexPath section]]; Entry *entry = [sectionDict objectAtIndex:[indexPath row]]; NSString *value = @""; [cell hideDeleteButton:NO]; - if (indexPath.section == ContactSections_First_Name) { + if (indexPath.section == ContactSections_FirstName) { value = (NSString *)CFBridgingRelease( - ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_First_Name])); + ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_FirstName])); [cell hideDeleteButton:YES]; - } else if (indexPath.section == ContactSections_Last_Name) { + } else if (indexPath.section == ContactSections_LastName) { value = (NSString *)CFBridgingRelease( - ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_Last_Name])); + ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_LastName])); [cell hideDeleteButton:YES]; } else if ([indexPath section] == ContactSections_Number) { ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty); @@ -565,30 +546,6 @@ return cell; } -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [tableView deselectRowAtIndexPath:indexPath animated:NO]; - NSMutableArray *sectionDict = [self getSectionData:[indexPath section]]; - Entry *entry = [sectionDict objectAtIndex:[indexPath row]]; - if ([self isEditing]) { - NSString *key = nil; - ABPropertyID property = [self propertyIDForSection:(ContactSections)indexPath.section]; - - if (property != kABInvalidPropertyType && property != kABPersonFirstNameProperty && - property != kABPersonLastNameProperty) { - ABMultiValueRef lMap = ABRecordCopyValue(contact, property); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - NSString *labelRef = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(lMap, index)); - if (labelRef != NULL) { - key = (NSString *)(labelRef); - } - CFRelease(lMap); - } - if (key != nil) { - editingIndexPath = indexPath; - } - } -} - - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { @@ -648,10 +605,10 @@ NSString *text = nil; BOOL canAddEntry = self.tableView.isEditing; NSString *addEntryName = nil; - if (section == ContactSections_First_Name && self.tableView.isEditing) { + if (section == ContactSections_FirstName && self.tableView.isEditing) { text = NSLocalizedString(@"First name", nil); canAddEntry = NO; - } else if (section == ContactSections_Last_Name && self.tableView.isEditing) { + } else if (section == ContactSections_LastName && self.tableView.isEditing) { text = NSLocalizedString(@"Last name", nil); canAddEntry = NO; } else if ([self getSectionData:section].count > 0 || self.tableView.isEditing) { @@ -711,40 +668,13 @@ forRowAtIndexPath:indexPath]; } -#pragma mark - ContactDetailsLabelDelegate Functions - -- (void)changeContactDetailsLabel:(NSString *)value { - if (value != nil) { - NSInteger section = editingIndexPath.section; - NSMutableArray *sectionDict = [self getSectionData:section]; - ABPropertyID property = [self propertyIDForSection:(int)section]; - Entry *entry = [sectionDict objectAtIndex:editingIndexPath.row]; - - if (property != kABInvalidPropertyType) { - ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonPhoneProperty); - ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap); - CFRelease(lcMap); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - ABMultiValueReplaceLabelAtIndex(lMap, (__bridge CFStringRef)(value), index); - ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, nil); - CFRelease(lMap); - } - - [self.tableView beginUpdates]; - [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:editingIndexPath] withRowAnimation:FALSE]; - [self.tableView reloadSectionIndexTitles]; - [self.tableView endUpdates]; - } - editingIndexPath = nil; -} - #pragma mark - UITextFieldDelegate Functions - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (contactDetailsDelegate != nil) { - [self performSelector:@selector(updateModification) withObject:nil afterDelay:0]; + [contactDetailsDelegate onModification:nil]; } return YES; } @@ -756,26 +686,25 @@ - (BOOL)textFieldShouldEndEditing:(UITextField *)textField { UIView *view = [textField superview]; - - // Find TableViewCell while (view != nil && ![view isKindOfClass:[UIContactDetailsCell class]]) view = [view superview]; if (view != nil) { UIContactDetailsCell *cell = (UIContactDetailsCell *)view; - NSIndexPath *path = [self.tableView indexPathForCell:cell]; - NSMutableArray *sectionDict = [self getSectionData:[path section]]; - Entry *entry = [sectionDict objectAtIndex:[path row]]; + // we cannot use indexPathForCell method here because if the cell is not visible anymore, + // it will return nil.. + NSIndexPath *path = cell.indexPath; // [self.tableView indexPathForCell:cell]; ContactSections sect = (ContactSections)[path section]; - ABPropertyID property = [self propertyIDForSection:sect]; NSString *value = [textField text]; + NSMutableArray *sectionDict = [self getSectionData:[path section]]; + Entry *entry = [sectionDict objectAtIndex:[path row]]; + switch (sect) { - case ContactSections_First_Name: - case ContactSections_Last_Name: { - // [cell.detailTextLabel setText:[textField text]]; + case ContactSections_FirstName: + case ContactSections_LastName: { CFErrorRef error = NULL; - ABRecordSetValue(contact, property, (__bridge CFTypeRef)([textField text]), (CFErrorRef *)&error); + ABRecordSetValue(contact, property, (__bridge CFTypeRef)value, (CFErrorRef *)&error); if (error != NULL) { LOGE(@"Error when saving property %i in contact %p: Fail(%@)", property, contact, [(__bridge NSError *)error localizedDescription]); @@ -805,15 +734,15 @@ LOGE(@"Not valid UIEditableTableViewCell"); } if (contactDetailsDelegate != nil) { - [self performSelector:@selector(updateModification) withObject:nil afterDelay:0]; + [contactDetailsDelegate onModification:nil]; } return TRUE; } - (BOOL)isValid { NSString *firstName = (NSString *)CFBridgingRelease( - ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_First_Name])); - NSString *lastName = (NSString *)CFBridgingRelease( - ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_Last_Name])); + ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_FirstName])); + NSString *lastName = + (NSString *)CFBridgingRelease(ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_LastName])); return firstName.length > 0 || lastName.length > 0; } @@ -829,8 +758,8 @@ } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { - if (section == 0 || (!self.tableView.isEditing && - (section == ContactSections_First_Name || section == ContactSections_Last_Name))) { + if (section == 0 || + (!self.tableView.isEditing && (section == ContactSections_FirstName || section == ContactSections_LastName))) { return 1e-5; } return [self tableView:tableView viewForHeaderInSection:section].frame.size.height; diff --git a/Classes/LinphoneUI/UIAssistantTextField.m b/Classes/LinphoneUI/UIAssistantTextField.m index 6e392b0ee..1a83a877a 100644 --- a/Classes/LinphoneUI/UIAssistantTextField.m +++ b/Classes/LinphoneUI/UIAssistantTextField.m @@ -11,7 +11,7 @@ @implementation UIAssistantTextField -INIT_WITH_COMMON { +INIT_WITH_COMMON_CF { self.delegate = self; return self; } diff --git a/Classes/LinphoneUI/UIBouncingView.m b/Classes/LinphoneUI/UIBouncingView.m index 99d285266..df2cf3490 100644 --- a/Classes/LinphoneUI/UIBouncingView.m +++ b/Classes/LinphoneUI/UIBouncingView.m @@ -17,7 +17,7 @@ static NSString *const kDisappearAnimation = @"disappear"; @implementation UIBouncingView -INIT_WITH_COMMON { +INIT_WITH_COMMON_CF { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(settingsUpdate:) name:kLinphoneSettingsUpdate diff --git a/Classes/LinphoneUI/UICamSwitch.m b/Classes/LinphoneUI/UICamSwitch.m index 6716ff59b..67d36e2cc 100644 --- a/Classes/LinphoneUI/UICamSwitch.m +++ b/Classes/LinphoneUI/UICamSwitch.m @@ -26,7 +26,7 @@ #pragma mark - Lifecycle Functions -INIT_WITH_COMMON { +INIT_WITH_COMMON_CF { [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; return self; } diff --git a/Classes/LinphoneUI/UIContactDetailsCell.h b/Classes/LinphoneUI/UIContactDetailsCell.h index e8192967e..e97b42529 100644 --- a/Classes/LinphoneUI/UIContactDetailsCell.h +++ b/Classes/LinphoneUI/UIContactDetailsCell.h @@ -23,6 +23,10 @@ @interface UIContactDetailsCell : UITableViewCell +// this is broken design... but we need this to know which cell was modified +// last... must be totally revamped +@property(strong) NSIndexPath *indexPath; + @property(weak, nonatomic) IBOutlet UIView *defaultView; @property(weak, nonatomic) IBOutlet UILabel *addressLabel; @property(weak, nonatomic) IBOutlet UITextField *editTextfield; diff --git a/Classes/LinphoneUI/UIIconButton.m b/Classes/LinphoneUI/UIIconButton.m index a3946f43a..80886bd40 100644 --- a/Classes/LinphoneUI/UIIconButton.m +++ b/Classes/LinphoneUI/UIIconButton.m @@ -12,7 +12,7 @@ @implementation UIIconButton -INIT_WITH_COMMON { +INIT_WITH_COMMON_CF { [super setImage:[self imageForState:UIControlStateNormal] forState:(UIControlStateHighlighted | UIControlStateSelected)]; [super setImage:[self imageForState:UIControlStateDisabled] diff --git a/Classes/LinphoneUI/UIRoundedImageView.m b/Classes/LinphoneUI/UIRoundedImageView.m index cf8202a3f..90847d109 100644 --- a/Classes/LinphoneUI/UIRoundedImageView.m +++ b/Classes/LinphoneUI/UIRoundedImageView.m @@ -14,7 +14,7 @@ UIView *borderView; } -INIT_WITH_COMMON { +INIT_WITH_COMMON_CF { borderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; borderView.layer.borderWidth = 10; borderView.layer.borderColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]].CGColor; diff --git a/Classes/LinphoneUI/UISpeakerButton.m b/Classes/LinphoneUI/UISpeakerButton.m index 0c4332024..8b0279666 100644 --- a/Classes/LinphoneUI/UISpeakerButton.m +++ b/Classes/LinphoneUI/UISpeakerButton.m @@ -39,7 +39,7 @@ static void audioRouteChangeListenerCallback(void *inUserData, // 1 [button update]; } -INIT_WITH_COMMON { +INIT_WITH_COMMON_CF { AudioSessionInitialize(NULL, NULL, NULL, NULL); OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, (__bridge void *)(self)); diff --git a/Classes/LinphoneUI/UIVideoButton.m b/Classes/LinphoneUI/UIVideoButton.m index d78a50656..0c1f5aebe 100644 --- a/Classes/LinphoneUI/UIVideoButton.m +++ b/Classes/LinphoneUI/UIVideoButton.m @@ -27,7 +27,7 @@ @synthesize waitView; -INIT_WITH_COMMON { +INIT_WITH_COMMON_CF { last_update_state = FALSE; return self; } diff --git a/Classes/SettingsView.m b/Classes/SettingsView.m index a835e6376..298fcd49e 100644 --- a/Classes/SettingsView.m +++ b/Classes/SettingsView.m @@ -252,7 +252,7 @@ @implementation UINavigationBarEx -INIT_WITH_COMMON { +INIT_WITH_COMMON_CF { [self setTintColor:[LINPHONE_MAIN_COLOR adjustHue:5.0f / 180.0f saturation:0.0f brightness:0.0f alpha:0.0f]]; return self; } diff --git a/Classes/Utils/Utils.h b/Classes/Utils/Utils.h index 03f1b6843..af581620b 100644 --- a/Classes/Utils/Utils.h +++ b/Classes/Utils/Utils.h @@ -94,7 +94,7 @@ typedef enum { /* Use that macro when you want to invoke a custom initialisation method on your class, whatever is using it (xib, source code, etc., tableview cell) */ -#define INIT_WITH_COMMON \ +#define INIT_WITH_COMMON_C \ -(instancetype)init { \ self = [super init]; \ [self commonInit]; \ @@ -105,9 +105,12 @@ typedef enum { [self commonInit]; \ return self; \ } \ + -(instancetype)commonInit + +#define INIT_WITH_COMMON_CF \ -(instancetype)initWithFrame : (CGRect)frame { \ self = [super initWithFrame:frame]; \ [self commonInit]; \ return self; \ } \ - -(instancetype)commonInit + INIT_WITH_COMMON_C diff --git a/TestsUI/ContactsTester.m b/TestsUI/ContactsTester.m index 70706942d..13310c236 100644 --- a/TestsUI/ContactsTester.m +++ b/TestsUI/ContactsTester.m @@ -47,13 +47,13 @@ traits:UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled | UIAccessibilityTraitSelected]; - [self setText:firstName forIndex:0 inSection:ContactSections_First_Name]; + [self setText:firstName forIndex:0 inSection:ContactSections_FirstName]; // entering text should enable the "edit" button [tester waitForViewWithAccessibilityLabel:@"Edit" traits:UIAccessibilityTraitButton | UIAccessibilityTraitSelected]; if (lastName) { - [self setText:lastName forIndex:0 inSection:ContactSections_Last_Name]; + [self setText:lastName forIndex:0 inSection:ContactSections_LastName]; } if (phone) { @@ -70,17 +70,18 @@ - (void)tapCellForRowAtIndexPath:(NSInteger)idx inSection:(NSInteger)section atX:(CGFloat)x { UITableView *tv = [self findTableView:@"Contact table"]; NSIndexPath *path = [NSIndexPath indexPathForRow:idx inSection:section]; - UITableViewCell *last = + UITableViewCell *cell = [tester waitForCellAtIndexPath:path inTableViewWithAccessibilityIdentifier:@"Contact table"]; - XCTAssertNotNil(last); + XCTAssertNotNil(cell); - CGRect cellFrame = [last.contentView convertRect:last.contentView.frame toView:tv]; - [tv tapAtPoint:CGPointMake(x > 0 ? x : cellFrame.size.width + x, cellFrame.origin.y + cellFrame.size.height / 2.)]; + CGRect cellFrame = [cell.contentView convertRect:cell.contentView.frame toView:tv]; + [tv tapAtPoint:CGPointMake(x > 0 ? x : tv.superview.frame.size.width + x, + cellFrame.origin.y + cellFrame.size.height / 2.)]; [tester waitForAnimationsToFinish]; } - (void)tapRemoveButtonForRowAtIndexPath:(NSInteger)idx inSection:(NSInteger)section { - [self tapCellForRowAtIndexPath:idx inSection:section atX:-10]; + [self tapCellForRowAtIndexPath:idx inSection:section atX:-7]; } - (void)addEntries:(NSArray *)numbers inSection:(NSInteger)section { @@ -100,12 +101,12 @@ } - (void)deleteContactEntryForRowAtIndexPath:(NSInteger)idx inSection:(NSInteger)section { - if ([tester tryFindingTappableViewWithAccessibilityLabel:@"Delete" error:nil]) { - [tester tapViewWithAccessibilityLabel:@"Delete"]; - } else { - // hack: Travis seems to be unable to click on delete for what ever reason + // if ([tester tryFindingTappableViewWithAccessibilityLabel:@"Delete" error:nil]) { + // [tester tapViewWithAccessibilityLabel:@"Delete"]; + // } else { + // hack: Travis seems to be unable to click on delete for what ever reason [self tapRemoveButtonForRowAtIndexPath:idx inSection:section]; - } + // } } #pragma mark - Tests @@ -129,7 +130,6 @@ [tester tapViewWithAccessibilityLabel:fullName traits:UIAccessibilityTraitStaticText]; [tester tapViewWithAccessibilityLabel:@"Edit"]; - [tester scrollViewWithAccessibilityIdentifier:@"Contact table" byFractionOfSizeHorizontal:0 vertical:-0.9]; [tester tapViewWithAccessibilityLabel:@"Delete"]; [tester tapViewWithAccessibilityLabel:@"DELETE"]; @@ -148,11 +148,11 @@ [tester tapViewWithAccessibilityLabel:@"Edit"]; // remove all numbers for (NSInteger i = 0; i < phones.count; i++) { - [self tapRemoveButtonForRowAtIndexPath:0 inSection:ContactSections_Number]; + [self deleteContactEntryForRowAtIndexPath:0 inSection:ContactSections_Number]; } // remove all SIPs for (NSInteger i = 0; i < SIPs.count; i++) { - [self tapRemoveButtonForRowAtIndexPath:0 inSection:ContactSections_Sip]; + [self deleteContactEntryForRowAtIndexPath:0 inSection:ContactSections_Sip]; } [tester tapViewWithAccessibilityLabel:@"Edit"]; diff --git a/TestsUI/LinphoneTestCase.h b/TestsUI/LinphoneTestCase.h index cd31947e6..0ac72f0ee 100644 --- a/TestsUI/LinphoneTestCase.h +++ b/TestsUI/LinphoneTestCase.h @@ -10,6 +10,7 @@ #import #import "Utils.h" +#import "Log.h" @interface LinphoneTestCase : KIFTestCase @property BOOL invalidAccountSet;