mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
contacts list rm
This commit is contained in:
parent
bacaabac60
commit
eed495e4e5
13 changed files with 200 additions and 156 deletions
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="8191" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ContactsListView">
|
||||
|
|
@ -10,10 +10,10 @@
|
|||
<outlet property="addButton" destination="6" id="91"/>
|
||||
<outlet property="allButton" destination="4" id="27"/>
|
||||
<outlet property="backButton" destination="87" id="90"/>
|
||||
<outlet property="deleteButton" destination="aJI-VJ-xN6" id="nXJ-rR-zmW"/>
|
||||
<outlet property="linphoneButton" destination="5" id="31"/>
|
||||
<outlet property="searchBar" destination="5jE-oF-d45" id="xfS-xo-2Bm"/>
|
||||
<outlet property="tableController" destination="TJG-JZ-YRR" id="0lt-gC-EOm"/>
|
||||
<outlet property="tableView" destination="zOo-FS-W6l" id="T4d-56-Bgi"/>
|
||||
<outlet property="topBar" destination="3" id="w1O-2o-b18"/>
|
||||
<outlet property="view" destination="2" id="16"/>
|
||||
</connections>
|
||||
|
|
@ -127,10 +127,13 @@
|
|||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<state key="highlighted" backgroundImage="color_E.png"/>
|
||||
<connections>
|
||||
<action selector="onDeleteClick:" destination="-1" eventType="touchUpInside" id="XEW-2B-Q5j"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="zOo-FS-W6l" userLabel="tableView">
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="zOo-FS-W6l" userLabel="tableView">
|
||||
<rect key="frame" x="0.0" y="86" width="375" height="475"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
|
|
@ -176,4 +179,9 @@
|
|||
<image name="delete.png" width="21" height="27"/>
|
||||
<image name="edit_list.png" width="29" height="28"/>
|
||||
</resources>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -75,34 +75,12 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
|
|||
}
|
||||
|
||||
- (void)removeContact {
|
||||
if (contact == NULL) {
|
||||
[PhoneMainView.instance popCurrentView];
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove contact from book
|
||||
if (ABRecordGetRecordID(contact) != kABRecordInvalidID) {
|
||||
CFErrorRef error = NULL;
|
||||
ABAddressBookRemoveRecord(addressBook, contact, (CFErrorRef *)&error);
|
||||
if (error != NULL) {
|
||||
LOGE(@"Remove contact %p: Fail(%@)", contact, [(__bridge NSError *)error localizedDescription]);
|
||||
} else {
|
||||
LOGI(@"Remove contact %p: Success!", contact);
|
||||
}
|
||||
contact = NULL;
|
||||
|
||||
// Save address book
|
||||
error = NULL;
|
||||
if (contact != NULL) {
|
||||
inhibUpdate = TRUE;
|
||||
ABAddressBookSave(addressBook, (CFErrorRef *)&error);
|
||||
[[[LinphoneManager instance] fastAddressBook] removeContact:contact];
|
||||
inhibUpdate = FALSE;
|
||||
if (error != NULL) {
|
||||
LOGE(@"Save AddressBook: Fail(%@)", [(__bridge NSError *)error localizedDescription]);
|
||||
} else {
|
||||
LOGI(@"Save AddressBook: Success!");
|
||||
}
|
||||
[[LinphoneManager instance].fastAddressBook reload];
|
||||
}
|
||||
[PhoneMainView.instance popCurrentView];
|
||||
}
|
||||
|
||||
- (void)saveData {
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
#import <AddressBook/AddressBook.h>
|
||||
|
||||
#import "UICheckBoxTVTableViewController.h"
|
||||
|
||||
#import "OrderedDictionary.h"
|
||||
|
||||
@interface ContactsListTableView : UITableViewController {
|
||||
@interface ContactsListTableView : UICheckBoxTVTableViewController {
|
||||
@private
|
||||
OrderedDictionary *addressBookMap;
|
||||
NSMutableDictionary *avatarMap;
|
||||
|
|
|
|||
|
|
@ -82,6 +82,41 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) {
|
|||
return (int)(within_sentence != NULL ? 0 : fuzzy_word + strlen(fuzzy_word) - c);
|
||||
}
|
||||
|
||||
- (NSString *)displayNameForContact:(ABRecordRef)person {
|
||||
NSString *lFirstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
|
||||
NSString *lLocalizedFirstName = [FastAddressBook localizedLabel:lFirstName];
|
||||
NSString *lLastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
|
||||
NSString *lLocalizedLastName = [FastAddressBook localizedLabel:lLastName];
|
||||
NSString *lOrganization = CFBridgingRelease(ABRecordCopyValue(person, kABPersonOrganizationProperty));
|
||||
NSString *lLocalizedlOrganization = [FastAddressBook localizedLabel:lOrganization];
|
||||
|
||||
NSString *name = nil;
|
||||
if (lLocalizedFirstName.length && lLocalizedLastName.length) {
|
||||
name = [NSString stringWithFormat:@"%@ %@", lLocalizedFirstName, lLocalizedLastName];
|
||||
} else if (lLocalizedLastName.length) {
|
||||
name = [NSString stringWithFormat:@"%@", lLocalizedLastName];
|
||||
} else if (lLocalizedFirstName.length) {
|
||||
name = [NSString stringWithFormat:@"%@", lLocalizedFirstName];
|
||||
} else if (lLocalizedlOrganization.length) {
|
||||
name = [NSString stringWithFormat:@"%@", lLocalizedlOrganization];
|
||||
}
|
||||
|
||||
if (name != nil && [name length] > 0) {
|
||||
// Add the contact only if it fuzzy match filter too (if any)
|
||||
if ([ContactSelection getNameOrEmailFilter] == nil ||
|
||||
(ms_strcmpfuz([[[ContactSelection getNameOrEmailFilter] lowercaseString] UTF8String],
|
||||
[[name lowercaseString] UTF8String]) == 0)) {
|
||||
|
||||
// Sort contacts by first letter. We need to translate the name to ASCII first, because of UTF-8
|
||||
// issues. For instance expected order would be: Alberta(A tilde) before ASylvano.
|
||||
NSData *name2ASCIIdata = [name dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
|
||||
NSString *name2ASCII = [[NSString alloc] initWithData:name2ASCIIdata encoding:NSASCIIStringEncoding];
|
||||
return name2ASCII;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)loadData {
|
||||
LOGI(@"Load contact list");
|
||||
@synchronized(addressBookMap) {
|
||||
|
|
@ -109,57 +144,24 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) {
|
|||
CFRelease(personEmailAddresses);
|
||||
}
|
||||
|
||||
if (add) {
|
||||
NSString *lFirstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
|
||||
NSString *lLocalizedFirstName = [FastAddressBook localizedLabel:lFirstName];
|
||||
NSString *lLastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
|
||||
NSString *lLocalizedLastName = [FastAddressBook localizedLabel:lLastName];
|
||||
NSString *lOrganization = CFBridgingRelease(ABRecordCopyValue(person, kABPersonOrganizationProperty));
|
||||
NSString *lLocalizedlOrganization = [FastAddressBook localizedLabel:lOrganization];
|
||||
NSString *name = [self displayNameForContact:person];
|
||||
if (add && name != nil) {
|
||||
NSString *firstChar = [[name substringToIndex:1] uppercaseString];
|
||||
|
||||
NSString *name = nil;
|
||||
if (lLocalizedFirstName.length && lLocalizedLastName.length) {
|
||||
name = [NSString stringWithFormat:@"%@ %@", lLocalizedFirstName, lLocalizedLastName];
|
||||
} else if (lLocalizedLastName.length) {
|
||||
name = [NSString stringWithFormat:@"%@", lLocalizedLastName];
|
||||
} else if (lLocalizedFirstName.length) {
|
||||
name = [NSString stringWithFormat:@"%@", lLocalizedFirstName];
|
||||
} else if (lLocalizedlOrganization.length) {
|
||||
name = [NSString stringWithFormat:@"%@", lLocalizedlOrganization];
|
||||
// Put in correct subDic
|
||||
if ([firstChar characterAtIndex:0] < 'A' || [firstChar characterAtIndex:0] > 'Z') {
|
||||
firstChar = @"#";
|
||||
}
|
||||
|
||||
if (name != nil && [name length] > 0) {
|
||||
// Add the contact only if it fuzzy match filter too (if any)
|
||||
if ([ContactSelection getNameOrEmailFilter] == nil ||
|
||||
(ms_strcmpfuz([[[ContactSelection getNameOrEmailFilter] lowercaseString] UTF8String],
|
||||
[[name lowercaseString] UTF8String]) == 0)) {
|
||||
|
||||
// Sort contacts by first letter. We need to translate the name to ASCII first, because of UTF-8
|
||||
// issues. For instance expected order would be: Alberta(A tilde) before ASylvano.
|
||||
NSData *name2ASCIIdata =
|
||||
[name dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
|
||||
NSString *name2ASCII =
|
||||
[[NSString alloc] initWithData:name2ASCIIdata encoding:NSASCIIStringEncoding];
|
||||
NSString *firstChar = [[name2ASCII substringToIndex:1] uppercaseString];
|
||||
|
||||
// Put in correct subDic
|
||||
if ([firstChar characterAtIndex:0] < 'A' || [firstChar characterAtIndex:0] > 'Z') {
|
||||
firstChar = @"#";
|
||||
}
|
||||
OrderedDictionary *subDic = [addressBookMap objectForKey:firstChar];
|
||||
if (subDic == nil) {
|
||||
subDic = [[OrderedDictionary alloc] init];
|
||||
[addressBookMap insertObject:subDic
|
||||
forKey:firstChar
|
||||
selector:@selector(caseInsensitiveCompare:)];
|
||||
}
|
||||
[subDic insertObject:lPerson forKey:name2ASCII selector:@selector(caseInsensitiveCompare:)];
|
||||
}
|
||||
OrderedDictionary *subDic = [addressBookMap objectForKey:firstChar];
|
||||
if (subDic == nil) {
|
||||
subDic = [[OrderedDictionary alloc] init];
|
||||
[addressBookMap insertObject:subDic forKey:firstChar selector:@selector(caseInsensitiveCompare:)];
|
||||
}
|
||||
[subDic insertObject:lPerson forKey:name selector:@selector(caseInsensitiveCompare:)];
|
||||
}
|
||||
}
|
||||
}
|
||||
[self.tableView reloadData];
|
||||
[super loadData];
|
||||
}
|
||||
|
||||
static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
|
||||
|
|
@ -184,7 +186,7 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
|
|||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
static NSString *kCellId = @"UIContactCell";
|
||||
NSString *kCellId = NSStringFromClass(UIContactCell.class);
|
||||
UIContactCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
|
||||
if (cell == nil) {
|
||||
cell = [[UIContactCell alloc] initWithIdentifier:kCellId];
|
||||
|
|
@ -195,24 +197,15 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
|
|||
ABRecordRef contact = (__bridge ABRecordRef)([subDic objectForKey:key]);
|
||||
|
||||
// Cached avatar
|
||||
UIImage *image = nil;
|
||||
id data = [avatarMap objectForKey:[NSNumber numberWithInt:ABRecordGetRecordID(contact)]];
|
||||
if (data == nil) {
|
||||
image = [FastAddressBook getContactImage:contact thumbnail:true];
|
||||
if (image != nil) {
|
||||
[avatarMap setObject:image forKey:[NSNumber numberWithInt:ABRecordGetRecordID(contact)]];
|
||||
} else {
|
||||
[avatarMap setObject:[NSNull null] forKey:[NSNumber numberWithInt:ABRecordGetRecordID(contact)]];
|
||||
}
|
||||
} else if (data != [NSNull null]) {
|
||||
image = data;
|
||||
}
|
||||
UIImage *image = [avatarMap objectForKey:[NSNumber numberWithInt:ABRecordGetRecordID(contact)]];
|
||||
if (image == nil) {
|
||||
image = [UIImage imageNamed:@"avatar_unknown_small.png"];
|
||||
image = [FastAddressBook getContactImage:contact thumbnail:true];
|
||||
[avatarMap setObject:image forKey:[NSNumber numberWithInt:ABRecordGetRecordID(contact)]];
|
||||
}
|
||||
[[cell avatarImage] setImage:image];
|
||||
|
||||
[cell.avatarImage setImage:image];
|
||||
[cell setContact:contact];
|
||||
[super accessoryForCell:cell atPath:indexPath];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
|
@ -221,28 +214,43 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
|
|||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
OrderedDictionary *subDic = [addressBookMap objectForKey:[addressBookMap keyAtIndex:[indexPath section]]];
|
||||
ABRecordRef lPerson = (__bridge ABRecordRef)([subDic objectForKey:[subDic keyAtIndex:[indexPath row]]]);
|
||||
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
|
||||
if (![self isEditing]) {
|
||||
OrderedDictionary *subDic = [addressBookMap objectForKey:[addressBookMap keyAtIndex:[indexPath section]]];
|
||||
ABRecordRef lPerson = (__bridge ABRecordRef)([subDic objectForKey:[subDic keyAtIndex:[indexPath row]]]);
|
||||
|
||||
// Go to Contact details view
|
||||
ContactDetailsView *view = VIEW(ContactDetailsView);
|
||||
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE];
|
||||
if ([ContactSelection getSelectionMode] != ContactSelectionModeEdit) {
|
||||
[view setContact:lPerson];
|
||||
} else {
|
||||
[view editContact:lPerson address:[ContactSelection getAddAddress]];
|
||||
// Go to Contact details view
|
||||
ContactDetailsView *view = VIEW(ContactDetailsView);
|
||||
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE];
|
||||
if ([ContactSelection getSelectionMode] != ContactSelectionModeEdit) {
|
||||
[view setContact:lPerson];
|
||||
} else {
|
||||
[view editContact:lPerson address:[ContactSelection getAddAddress]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDelegate Functions
|
||||
|
||||
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView
|
||||
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
// Detemine if it's in editing mode
|
||||
if (self.editing) {
|
||||
return UITableViewCellEditingStyleDelete;
|
||||
- (void)tableView:(UITableView *)tableView
|
||||
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
|
||||
forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete) {
|
||||
ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(self));
|
||||
[tableView beginUpdates];
|
||||
OrderedDictionary *subDic = [addressBookMap objectForKey:[addressBookMap keyAtIndex:[indexPath section]]];
|
||||
NSString *key = [[subDic allKeys] objectAtIndex:[indexPath row]];
|
||||
ABRecordRef contact = (__bridge ABRecordRef)([subDic objectForKey:key]);
|
||||
NSString *firstChar = [[self displayNameForContact:contact] substringToIndex:1];
|
||||
[[addressBookMap objectForKey:firstChar] removeObjectForKey:[self displayNameForContact:contact]];
|
||||
if ([tableView numberOfRowsInSection:indexPath.section] == 1) {
|
||||
[addressBookMap removeObjectForKey:firstChar];
|
||||
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section]
|
||||
withRowAnimation:UITableViewRowAnimationFade];
|
||||
}
|
||||
[[[LinphoneManager instance] fastAddressBook] removeContact:contact];
|
||||
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
|
||||
withRowAnimation:UITableViewRowAnimationFade];
|
||||
[tableView endUpdates];
|
||||
ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(self));
|
||||
}
|
||||
return UITableViewCellEditingStyleNone;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#import "UICompositeView.h"
|
||||
#import "ContactsListTableView.h"
|
||||
#import "UIIconButton.h"
|
||||
|
||||
typedef enum _ContactSelectionMode {
|
||||
ContactSelectionModeNone,
|
||||
|
|
@ -79,19 +80,19 @@ typedef enum _ContactSelectionMode {
|
|||
: UIViewController <UICompositeViewDelegate, ABPeoplePickerNavigationControllerDelegate, UISearchBarDelegate>
|
||||
|
||||
@property(strong, nonatomic) IBOutlet ContactsListTableView *tableController;
|
||||
@property(nonatomic, strong) IBOutlet UINavigationController *sysViewController;
|
||||
@property(strong, nonatomic) IBOutlet UIView *topBar;
|
||||
@property(nonatomic, strong) IBOutlet UIButton *allButton;
|
||||
@property(nonatomic, strong) IBOutlet UIButton *linphoneButton;
|
||||
@property(nonatomic, strong) IBOutlet UIButton *backButton;
|
||||
@property(nonatomic, strong) IBOutlet UIButton *addButton;
|
||||
@property(strong, nonatomic) IBOutlet UISearchBar *searchBar;
|
||||
@property(weak, nonatomic) IBOutlet UITableView *tableView;
|
||||
@property(weak, nonatomic) IBOutlet UIIconButton *deleteButton;
|
||||
|
||||
- (IBAction)onAllClick:(id)event;
|
||||
- (IBAction)onLinphoneClick:(id)event;
|
||||
- (IBAction)onAddContactClick:(id)event;
|
||||
- (IBAction)onBackClick:(id)event;
|
||||
- (IBAction)onEditClick:(id)sender;
|
||||
- (IBAction)onDeleteClick:(id)sender;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -78,10 +78,6 @@ static NSString *sNameOrEmailFilter;
|
|||
@implementation ContactsListView
|
||||
|
||||
@synthesize tableController;
|
||||
@synthesize tableView;
|
||||
|
||||
@synthesize sysViewController;
|
||||
|
||||
@synthesize allButton;
|
||||
@synthesize linphoneButton;
|
||||
@synthesize backButton;
|
||||
|
|
@ -129,7 +125,7 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
subViewFrame.size.height -= self.topBar.frame.size.height;
|
||||
[UIView animateWithDuration:0.2
|
||||
animations:^{
|
||||
self.tableView.frame = subViewFrame;
|
||||
self.tableController.tableView.frame = subViewFrame;
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
@ -239,6 +235,21 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
}
|
||||
|
||||
- (IBAction)onEditClick:(id)sender {
|
||||
[tableController setEditing:!tableController.isEditing animated:TRUE];
|
||||
_deleteButton.hidden = !tableController.isEditing;
|
||||
addButton.hidden = !_deleteButton.hidden;
|
||||
}
|
||||
|
||||
- (IBAction)onDeleteClick:(id)sender {
|
||||
NSString *msg =
|
||||
[NSString stringWithFormat:NSLocalizedString(@"Are you sure that you want to delete %d contacts?", nil),
|
||||
tableController.selectedItems.count];
|
||||
[UIConfirmationDialog ShowWithMessage:msg
|
||||
onCancelClick:nil
|
||||
onConfirmationClick:^() {
|
||||
[tableController removeSelection];
|
||||
[tableController loadData];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@
|
|||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
|
||||
if ([self isEditing]) {
|
||||
if (![self isEditing]) {
|
||||
LinphoneCallLog *callLog = [[_callLogs objectAtIndex:[indexPath row]] pointerValue];
|
||||
if (callLog != NULL && linphone_call_log_get_call_id(callLog) != NULL) {
|
||||
LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog);
|
||||
|
|
@ -150,15 +150,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView
|
||||
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
// Detemine if it's in editing mode
|
||||
if (self.editing) {
|
||||
return UITableViewCellEditingStyleDelete;
|
||||
}
|
||||
return UITableViewCellEditingStyleNone;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView
|
||||
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
|
||||
forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
|
|
|||
|
|
@ -22,13 +22,6 @@
|
|||
|
||||
@implementation HistoryListView
|
||||
|
||||
@synthesize tableController;
|
||||
|
||||
@synthesize allButton;
|
||||
@synthesize missedButton;
|
||||
@synthesize editButton;
|
||||
@synthesize deleteButton;
|
||||
|
||||
typedef enum _HistoryView { History_All, History_Missed, History_MAX } HistoryView;
|
||||
|
||||
#pragma mark - Lifecycle Functions
|
||||
|
|
@ -62,11 +55,11 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
if ([tableController isEditing]) {
|
||||
[tableController setEditing:FALSE animated:FALSE];
|
||||
if ([_tableController isEditing]) {
|
||||
[_tableController setEditing:FALSE animated:FALSE];
|
||||
}
|
||||
[deleteButton setHidden:TRUE];
|
||||
[editButton setOff];
|
||||
[_deleteButton setHidden:TRUE];
|
||||
[_editButton setOff];
|
||||
[self changeView:History_All];
|
||||
|
||||
// Reset missed call
|
||||
|
|
@ -88,26 +81,26 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
#pragma mark -
|
||||
|
||||
- (void)hideEditIfNeeded {
|
||||
editButton.hidden = ([tableController tableView:tableController.tableView numberOfRowsInSection:0] == 0);
|
||||
if ([editButton isSelected]) {
|
||||
[editButton toggle];
|
||||
_editButton.hidden = ([_tableController tableView:_tableController.tableView numberOfRowsInSection:0] == 0);
|
||||
if ([_editButton isSelected]) {
|
||||
[_editButton toggle];
|
||||
[self onEditClick:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)changeView:(HistoryView)view {
|
||||
if (view == History_All) {
|
||||
allButton.selected = TRUE;
|
||||
[tableController setMissedFilter:FALSE];
|
||||
_allButton.selected = TRUE;
|
||||
[_tableController setMissedFilter:FALSE];
|
||||
} else {
|
||||
allButton.selected = FALSE;
|
||||
_allButton.selected = FALSE;
|
||||
}
|
||||
|
||||
if (view == History_Missed) {
|
||||
missedButton.selected = TRUE;
|
||||
[tableController setMissedFilter:TRUE];
|
||||
_missedButton.selected = TRUE;
|
||||
[_tableController setMissedFilter:TRUE];
|
||||
} else {
|
||||
missedButton.selected = FALSE;
|
||||
_missedButton.selected = FALSE;
|
||||
}
|
||||
[self hideEditIfNeeded];
|
||||
}
|
||||
|
|
@ -123,19 +116,19 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
}
|
||||
|
||||
- (IBAction)onEditClick:(id)event {
|
||||
[tableController setEditing:![tableController isEditing] animated:TRUE];
|
||||
[deleteButton setHidden:![tableController isEditing]];
|
||||
[_tableController setEditing:!_tableController.isEditing animated:TRUE];
|
||||
_deleteButton.hidden = !_tableController.isEditing;
|
||||
}
|
||||
|
||||
- (IBAction)onDeleteClick:(id)event {
|
||||
NSString *msg =
|
||||
[NSString stringWithFormat:NSLocalizedString(@"Are you sure that you want to delete %d history?", nil),
|
||||
tableController.selectedItems.count];
|
||||
_tableController.selectedItems.count];
|
||||
[UIConfirmationDialog ShowWithMessage:msg
|
||||
onCancelClick:nil
|
||||
onConfirmationClick:^() {
|
||||
[tableController removeSelection];
|
||||
[tableController loadData];
|
||||
[_tableController removeSelection];
|
||||
[_tableController loadData];
|
||||
[self hideEditIfNeeded];
|
||||
}];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,19 @@
|
|||
[self accessoryForCell:cell atPath:indexPath];
|
||||
}
|
||||
|
||||
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView
|
||||
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
// Detemine if it's in editing mode
|
||||
if (self.editing) {
|
||||
return UITableViewCellEditingStyleDelete;
|
||||
}
|
||||
return UITableViewCellEditingStyleNone;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)accessoryForCell:(UITableViewCell *)cell atPath:(NSIndexPath *)indexPath {
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
if ([self isEditing]) {
|
||||
UIImage *image = nil;
|
||||
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
|
||||
|
|
@ -80,7 +92,7 @@
|
|||
- (void)removeSelection {
|
||||
// we must iterate through selected items in reverse order
|
||||
[_selectedItems sortUsingComparator:^(NSIndexPath *obj1, NSIndexPath *obj2) {
|
||||
return [obj1 compare:obj2];
|
||||
return [obj2 compare:obj1];
|
||||
}];
|
||||
for (NSIndexPath *indexPath in _selectedItems) {
|
||||
[self tableView:self.tableView
|
||||
|
|
|
|||
|
|
@ -35,9 +35,11 @@
|
|||
NSArray *arrayOfViews =
|
||||
[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil];
|
||||
|
||||
if ([arrayOfViews count] >= 1) {
|
||||
[self.contentView addSubview:[arrayOfViews objectAtIndex:0]];
|
||||
}
|
||||
// resize cell to match .nib size. It is needed when resized the cell to
|
||||
// correctly adapt its height too
|
||||
UIView *sub = ((UIView *)[arrayOfViews objectAtIndex:0]);
|
||||
[self setFrame:CGRectMake(0, 0, sub.frame.size.width, sub.frame.size.height)];
|
||||
[self addSubview:sub];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
@ -77,4 +79,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)setEditing:(BOOL)editing {
|
||||
[self setEditing:editing animated:FALSE];
|
||||
}
|
||||
|
||||
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
|
||||
if (animated) {
|
||||
[UIView beginAnimations:nil context:nil];
|
||||
[UIView setAnimationDuration:0.3];
|
||||
}
|
||||
if (animated) {
|
||||
[UIView commitAnimations];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
UIView *sub = ((UIView *)[arrayOfViews objectAtIndex:0]);
|
||||
[self setFrame:CGRectMake(0, 0, sub.frame.size.width, sub.frame.size.height)];
|
||||
[self addSubview:sub];
|
||||
self.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
callLog = NULL;
|
||||
}
|
||||
return self;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
- (void)reload;
|
||||
- (void)saveAddressBook;
|
||||
- (int)removeContact:(ABRecordRef)contact;
|
||||
|
||||
+ (BOOL)isAuthorized;
|
||||
|
||||
|
|
|
|||
|
|
@ -341,4 +341,28 @@ void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void
|
|||
return ret;
|
||||
}
|
||||
|
||||
- (int)removeContact:(ABRecordRef)contact {
|
||||
// Remove contact from book
|
||||
if (contact && ABRecordGetRecordID(contact) != kABRecordInvalidID) {
|
||||
CFErrorRef error = NULL;
|
||||
ABAddressBookRemoveRecord(addressBook, contact, (CFErrorRef *)&error);
|
||||
if (error != NULL) {
|
||||
LOGE(@"Remove contact %p: Fail(%@)", contact, [(__bridge NSError *)error localizedDescription]);
|
||||
} else {
|
||||
LOGI(@"Remove contact %p: Success!", contact);
|
||||
}
|
||||
contact = NULL;
|
||||
|
||||
// Save address book
|
||||
error = NULL;
|
||||
ABAddressBookSave(addressBook, (CFErrorRef *)&error);
|
||||
if (error != NULL) {
|
||||
LOGE(@"Save AddressBook: Fail(%@)", [(__bridge NSError *)error localizedDescription]);
|
||||
} else {
|
||||
LOGI(@"Save AddressBook: Success!");
|
||||
}
|
||||
return error ? -1 : 0;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
@end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue