contact: factorize lots of lowlevel code in a single class (in progress)

parent 0342e7b0
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
......@@ -510,7 +510,7 @@
</view>
<view tag="47" contentMode="scaleToFill" id="mga-O5-mUn" userLabel="bottomBar">
<rect key="frame" x="0.0" y="499" width="375" height="126"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<view tag="48" contentMode="scaleToFill" id="OIH-ek-VgL" userLabel="higherBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="63"/>
......@@ -601,7 +601,7 @@
<subviews>
<button opaque="NO" tag="57" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="SRu-dB-r3e" userLabel="numpadButton" customClass="UIToggleButton">
<rect key="frame" x="0.0" y="0.0" width="94" height="63"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<state key="normal" image="footer_dialer_default.png" backgroundImage="color_C.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
......@@ -624,7 +624,7 @@
</button>
<button opaque="NO" tag="59" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="t7u-65-OPV" userLabel="chatButton" customClass="UIIconButton">
<rect key="frame" x="281" y="0.0" width="94" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Hangup"/>
<state key="normal" image="footer_chat_default.png" backgroundImage="color_C.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
......@@ -656,6 +656,7 @@
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</subviews>
<color key="backgroundColor" red="0.2666666667" green="0.2666666667" blue="0.2666666667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
</view>
......@@ -1196,7 +1197,7 @@
<subviews>
<button opaque="NO" tag="57" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Fyf-if-w6d" userLabel="numpadButton" customClass="UIToggleButton">
<rect key="frame" x="0.0" y="0.0" width="83" height="63"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<state key="normal" image="footer_dialer_default.png" backgroundImage="color_C.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
......@@ -1219,7 +1220,7 @@
</button>
<button opaque="NO" tag="59" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Dh2-iA-2NB" userLabel="chatButton" customClass="UIIconButton">
<rect key="frame" x="250" y="0.0" width="84" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Hangup"/>
<state key="normal" image="footer_chat_default.png" backgroundImage="color_C.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
......@@ -281,7 +281,7 @@
<tableViewController id="20" userLabel="tableController" customClass="ContactDetailsTableView">
<extendedEdge key="edgesForExtendedLayout"/>
<connections>
<outlet property="contactDetailsDelegate" destination="-1" id="53"/>
<outlet property="editButton" destination="8" id="wZf-wX-YIu"/>
<outlet property="view" destination="19" id="26"/>
</connections>
</tableViewController>
......
//
// Contact.h
// linphone
//
// Created by Gautier Pelloux-Prayer on 12/01/16.
//
//
#import <Foundation/Foundation.h>
#import <AddressBook/AddressBook.h>
@interface Contact : NSObject
@property(nonatomic, assign) NSString *firstName;
@property(nonatomic, assign) NSString *lastName;
@property(nonatomic, strong) NSMutableArray *sipAddresses;
@property(nonatomic, strong) NSMutableArray *emails;
@property(nonatomic, strong) NSMutableArray *phoneNumbers;
- (instancetype)initWithPerson:(ABRecordRef)person;
- (BOOL)setSipAddress:(NSString *)sip atIndex:(NSInteger)index;
- (BOOL)setEmail:(NSString *)email atIndex:(NSInteger)index;
- (BOOL)setPhoneNumber:(NSString *)phone atIndex:(NSInteger)index;
- (BOOL)addSipAddress:(NSString *)sip;
- (BOOL)addEmail:(NSString *)email;
- (BOOL)addPhoneNumber:(NSString *)phone;
- (BOOL)removeSipAddressAtIndex:(NSInteger)index;
- (BOOL)removePhoneNumberAtIndex:(NSInteger)index;
- (BOOL)removeEmailAtIndex:(NSInteger)index;
@end
//
// Contact.m
// linphone
//
// Created by Gautier Pelloux-Prayer on 12/01/16.
//
//
#import "Contact.h"
@implementation Contact {
ABRecordRef person;
}
- (instancetype)initWithPerson:(ABRecordRef)aperson {
self = [super init];
person = aperson;
[self loadFields];
LOGI(@"Contact %@ %@ initialized with %d phones, %d sip, %d emails", self.firstName ?: @"", self.lastName ?: @"",
self.phoneNumbers.count, self.sipAddresses.count, self.emails.count);
return self;
}
- (void)dealloc {
if (person != nil && ABRecordGetRecordID(person) == kABRecordInvalidID) {
CFRelease(person);
}
}
- (void)loadFields {
// First and Last name
{
_firstName = (NSString *)CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
_lastName = (NSString *)CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
}
// Phone numbers
{
NSMutableArray *phones = [[NSMutableArray alloc] init];
ABMultiValueRef map = ABRecordCopyValue(person, kABPersonPhoneProperty);
if (map) {
for (int i = 0; i < ABMultiValueGetCount(map); ++i) {
ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(map, i);
NSInteger index = ABMultiValueGetIndexForIdentifier(map, identifier);
if (index != -1) {
NSString *valueRef = CFBridgingRelease(ABMultiValueCopyValueAtIndex(map, index));
if (valueRef != NULL) {
[phones addObject:[FastAddressBook localizedLabel:valueRef]];
}
}
}
CFRelease(map);
}
_phoneNumbers = phones;
}
// SIP (IM)
{
NSMutableArray *sip = [[NSMutableArray alloc] init];
ABMultiValueRef map = ABRecordCopyValue(person, kABPersonInstantMessageProperty);
if (map) {
for (int i = 0; i < ABMultiValueGetCount(map); ++i) {
CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(map, i);
if (CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) {
if (CFStringCompare((CFStringRef)[LinphoneManager instance].contactSipField,
CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey),
kCFCompareCaseInsensitive) == 0) {
NSString *value = (NSString *)(CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey));
CFRelease(lDict);
if (value != NULL) {
[sip addObject:value];
}
}
}
}
CFRelease(map);
}
_sipAddresses = sip;
}
// Email
{
NSMutableArray *emails = [[NSMutableArray alloc] init];
ABMultiValueRef map = ABRecordCopyValue(person, kABPersonEmailProperty);
if (map) {
for (int i = 0; i < ABMultiValueGetCount(map); ++i) {
ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(map, i);
NSInteger index = ABMultiValueGetIndexForIdentifier(map, identifier);
if (index != -1) {
NSString *valueRef = CFBridgingRelease(ABMultiValueCopyValueAtIndex(map, index));
if (valueRef != NULL) {
[emails addObject:valueRef];
}
}
}
CFRelease(map);
}
_emails = emails;
}
}
#pragma mark - Setters
- (void)setFirstName:(NSString *)firstName {
if ([self replaceInProperty:kABPersonFirstNameProperty value:(__bridge CFTypeRef)(firstName)]) {
_firstName = firstName;
}
}
- (void)setLastName:(NSString *)lastName {
if ([self replaceInProperty:kABPersonLastNameProperty value:(__bridge CFTypeRef)(lastName)]) {
_lastName = lastName;
}
}
- (BOOL)replaceInProperty:(ABPropertyID)property value:(CFTypeRef)value {
CFErrorRef error = NULL;
if (!ABRecordSetValue(person, property, value, &error)) {
LOGE(@"Error when saving property %d in contact %p: Fail(%@)", property, person, error);
return NO;
}
return YES;
}
- (BOOL)replaceInProperty:(ABPropertyID)property value:(CFTypeRef)value atIndex:(NSInteger)index {
ABMultiValueRef lcMap = ABRecordCopyValue(person, property);
ABMutableMultiValueRef lMap;
if (lcMap != NULL) {
lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
} else {
lMap = ABMultiValueCreateMutable(kABStringPropertyType);
}
BOOL ret = ABMultiValueReplaceValueAtIndex(lMap, value, index);
if (ret) {
ret = [self replaceInProperty:property value:lMap];
} else {
LOGW(@"Could not replace %@ at index %d from property %d", value, index, property);
}
CFRelease(lMap);
return ret;
}
- (BOOL)addInProperty:(ABPropertyID)property value:(CFTypeRef)value {
ABMultiValueRef lcMap = ABRecordCopyValue(person, property);
ABMutableMultiValueRef lMap;
if (lcMap != NULL) {
lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
} else {
lMap = ABMultiValueCreateMutable(kABStringPropertyType);
}
// will display this field with our application name
CFStringRef label = (__bridge CFStringRef)[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
BOOL ret = ABMultiValueAddValueAndLabel(lMap, value, label, nil);
if (ret) {
ret = [self replaceInProperty:property value:lMap];
} else {
LOGW(@"Could not add %@ to property %d", value, property);
}
CFRelease(lMap);
return ret;
}
- (BOOL)removeInProperty:(ABPropertyID)property atIndex:(NSInteger)index {
ABMultiValueRef lcMap = ABRecordCopyValue(person, property);
ABMutableMultiValueRef lMap;
if (lcMap != NULL) {
lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
} else {
lMap = ABMultiValueCreateMutable(kABStringPropertyType);
}
BOOL ret = ABMultiValueRemoveValueAndLabelAtIndex(lMap, index);
if (ret) {
ret = [self replaceInProperty:property value:lMap];
} else {
LOGW(@"Could not remove at index %d from property %d", index, property);
}
CFRelease(lMap);
return ret;
}
- (BOOL)setSipAddress:(NSString *)sip atIndex:(NSInteger)index {
NSDictionary *lDict = @{
(NSString *) kABPersonInstantMessageUsernameKey : sip, (NSString *)
kABPersonInstantMessageServiceKey : LinphoneManager.instance.contactSipField
};
BOOL ret = [self replaceInProperty:kABPersonInstantMessageProperty value:(__bridge CFTypeRef)(lDict) atIndex:index];
if (ret) {
_sipAddresses[index] = sip;
}
return ret;
}
- (BOOL)setPhoneNumber:(NSString *)phone atIndex:(NSInteger)index {
BOOL ret = [self replaceInProperty:kABPersonPhoneProperty value:(__bridge CFTypeRef)(phone) atIndex:index];
if (ret) {
_phoneNumbers[index] = phone;
}
return ret;
}
- (BOOL)addSipAddress:(NSString *)sip {
NSDictionary *lDict = @{
(NSString *) kABPersonInstantMessageUsernameKey : sip, (NSString *)
kABPersonInstantMessageServiceKey : [LinphoneManager instance].contactSipField
};
BOOL ret = [self addInProperty:kABPersonInstantMessageProperty value:(__bridge CFTypeRef)(lDict)];
if (ret) {
[_sipAddresses addObject:sip];
}
return ret;
}
- (BOOL)removeSipAddressAtIndex:(NSInteger)index {
BOOL ret = [self removeInProperty:kABPersonInstantMessageProperty atIndex:index];
if (ret) {
[_sipAddresses removeObjectAtIndex:index];
}
return ret;
}
- (BOOL)addPhoneNumber:(NSString *)phone {
BOOL ret = [self addInProperty:kABPersonPhoneProperty value:(__bridge CFTypeRef)(phone)];
if (ret) {
[_phoneNumbers addObject:phone];
}
return ret;
}
- (BOOL)removePhoneNumberAtIndex:(NSInteger)index {
BOOL ret = [self removeInProperty:kABPersonPhoneProperty atIndex:index];
if (ret) {
[_phoneNumbers removeObjectAtIndex:index];
}
return ret;
}
- (BOOL)setEmail:(NSString *)email atIndex:(NSInteger)index {
BOOL ret = [self replaceInProperty:kABPersonEmailProperty value:(__bridge CFTypeRef)(email) atIndex:index];
if (ret) {
_emails[index] = email;
}
return ret;
}
- (BOOL)addEmail:(NSString *)email {
BOOL ret = [self addInProperty:kABPersonEmailProperty value:(__bridge CFTypeRef)(email)];
if (ret) {
[_emails addObject:email];
}
return ret;
}
- (BOOL)removeEmailAtIndex:(NSInteger)index {
BOOL ret = [self removeInProperty:kABPersonEmailProperty atIndex:index];
if (ret) {
[_emails removeObjectAtIndex:index];
}
return ret;
}
@end
/* ContactDetailsDelegate.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
@protocol ContactDetailsDelegate <NSObject>
- (void)onModification:(id)event;
@end
\ No newline at end of file
......@@ -20,7 +20,8 @@
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import "ContactDetailsDelegate.h"
#import "Contact.h"
#import "LinphoneUI/UIToggleButton.h"
typedef enum _ContactSections {
ContactSections_None = 0, // first section is empty because we cannot set header for first section
......@@ -32,19 +33,14 @@ typedef enum _ContactSections {
ContactSections_MAX
} ContactSections;
@interface ContactDetailsTableView : UITableViewController <UITextFieldDelegate> {
@private
NSMutableArray *dataCache;
NSMutableArray *labelArray;
}
@interface ContactDetailsTableView : UITableViewController <UITextFieldDelegate>
@property(nonatomic, assign, setter=setContact:) ABRecordRef contact;
@property(nonatomic, strong) IBOutlet id<ContactDetailsDelegate> contactDetailsDelegate;
@property(strong, nonatomic) Contact *contact;
@property(weak, nonatomic) IBOutlet UIToggleButton *editButton;
- (BOOL)isValid;
- (void)addPhoneField:(NSString *)number;
- (void)addSipField:(NSString *)address;
- (void)addEmailField:(NSString *)address;
- (void)setContact:(ABRecordRef)contact;
- (void)setContact:(Contact *)contact;
@end
This diff is collapsed.
......@@ -18,7 +18,6 @@
*/
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import "UICompositeView.h"
#import "UIToggleButton.h"
......@@ -26,8 +25,7 @@
#import "UIRoundedImageView.h"
#import "ImagePickerView.h"
@interface ContactDetailsView
: TPMultiLayoutViewController <UICompositeViewDelegate, ContactDetailsDelegate, ImagePickerDelegate> {
@interface ContactDetailsView : TPMultiLayoutViewController <UICompositeViewDelegate, ImagePickerDelegate> {
ABAddressBookRef addressBook;
BOOL inhibUpdate;
}
......
......@@ -52,7 +52,6 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
return;
}
LOGI(@"Reset data to contact %p", _contact);
ABRecordID recordID = ABRecordGetRecordID(_contact);
ABAddressBookRevert(addressBook);
_contact = ABAddressBookGetPersonWithRecordID(addressBook, recordID);
......@@ -60,8 +59,10 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
[PhoneMainView.instance popCurrentView];
return;
}
LOGI(@"Reset data to contact %p", _contact);
[_avatarImage setImage:[FastAddressBook imageForContact:_contact thumbnail:NO] bordered:NO withRoundedRadius:YES];
[_tableController setContact:_contact];
[_tableController setContact:[[Contact alloc] initWithPerson:_contact]];
}
static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
......@@ -118,11 +119,10 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
_contact = acontact;
[_avatarImage setImage:[FastAddressBook imageForContact:_contact thumbnail:NO] bordered:NO withRoundedRadius:YES];
[ContactDisplay setDisplayNameLabel:_nameLabel forContact:acontact];
[_tableController setContact:_contact];
[_tableController setContact:[[Contact alloc] initWithPerson:_contact]];
if (reload) {
[self setEditing:TRUE animated:FALSE];
[[_tableController tableView] reloadData];
}
}
......@@ -274,10 +274,8 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onEditClick:(id)event {
if (_tableController.isEditing) {
if ([_tableController isValid]) {
[self setEditing:FALSE];
[self saveData];
}
[self setEditing:FALSE];
[self saveData];
} else {
[self setEditing:TRUE];
}
......@@ -303,14 +301,6 @@ static UICompositeViewDescription *compositeDescription = nil;
}
}
- (void)onModification:(id)event {
if (!_tableController.isEditing || [_tableController isValid]) {
[_editButton setEnabled:TRUE];
} else {
[_editButton setEnabled:FALSE];
}
}
#pragma mark - Image picker delegate
- (void)imagePickerDelegateImage:(UIImage *)image info:(NSDictionary *)info {
......
......@@ -116,7 +116,7 @@ static UICompositeViewDescription *compositeDescription = nil;
if (tableController.isEditing) {
tableController.editing = NO;
}
[self update];
[self refreshButtons];
}
- (void)viewDidAppear:(BOOL)animated {
......@@ -144,20 +144,20 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)changeView:(ContactsCategory)view {
CGRect frame = _selectedButtonImage.frame;
if (view == ContactsAll) {
if (view == ContactsAll && !allButton.selected) {
frame.origin.x = allButton.frame.origin.x;
[ContactSelection setSipFilter:nil];
[ContactSelection enableEmailFilter:FALSE];
[tableController loadData];
allButton.selected = TRUE;
linphoneButton.selected = FALSE;
} else {
[tableController loadData];
} else if (view == ContactsLinphone && !linphoneButton.selected) {
frame.origin.x = linphoneButton.frame.origin.x;
[ContactSelection setSipFilter:LinphoneManager.instance.contactFilter];
[ContactSelection enableEmailFilter:FALSE];
[tableController loadData];
linphoneButton.selected = TRUE;
allButton.selected = FALSE;
[tableController loadData];
}
_selectedButtonImage.frame = frame;
}
......@@ -167,11 +167,6 @@ static UICompositeViewDescription *compositeDescription = nil;
[self changeView:[ContactSelection getSipFilter] ? ContactsLinphone : ContactsAll];
}
- (void)update {
[self refreshButtons];
[tableController loadData];
}
#pragma mark - Action Functions
- (IBAction)onAllClick:(id)event {
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIContactDetailsCell">
......@@ -28,16 +28,14 @@
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" minimumFontSize="17" id="dTn-Hc-bGM" userLabel="editTextField">
<rect key="frame" x="8" y="7" width="326" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<animations/>
<color key="backgroundColor" red="0.90588235289999997" green="0.90588235289999997" blue="0.90588235289999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<rect key="contentStretch" x="1.3877787807814457e-17" y="0.0" width="1" height="1"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<textInputTraits key="textInputTraits" returnKeyType="done"/>
</textField>
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="C2f-aP-xjR" userLabel="deleteButton" customClass="UIIconButton">
<rect key="frame" x="340" y="7" width="30" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<animations/>
<state key="normal" image="delete_field_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
......@@ -48,7 +46,6 @@
</connections>
</button>
</subviews>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="SR2-3m-6t5" userLabel="defaultView">
......@@ -58,7 +55,6 @@
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="ZbV-2Z-b4y" userLabel="callButton" customClass="UIIconButton">
<rect key="frame" x="135" y="40" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Call"/>
<state key="normal" image="call_start_body_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
......@@ -72,7 +68,6 @@
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="FDT-HY-OQZ" userLabel="chatButton" customClass="UIIconButton">
<rect key="frame" x="195" y="40" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Chat"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
......@@ -86,16 +81,13 @@
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="john.doe@sip.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="frB-ep-LWi" userLabel="addressLabel">
<rect key="frame" x="8" y="0.0" width="359" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<animations/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<animations/>
</view>
</subviews>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
......
......@@ -356,7 +356,8 @@ void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void
error = NULL;
ABAddressBookSave(addressBook, (CFErrorRef *)&error);
[self reload];
// TODO: stop reloading the whole address book but just clear the removed entries!
[self loadData];
if (error != NULL) {
LOGE(@"Save AddressBook: Fail(%@)", [(__bridge NSError *)error localizedDescription]);
......
......@@ -95,6 +95,7 @@
633888451BFB2C49001D5E7B /* HPGrowingTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 633888421BFB2C49001D5E7B /* HPGrowingTextView.m */; };
633888461BFB2C49001D5E7B /* HPTextViewInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = 633888441BFB2C49001D5E7B /* HPTextViewInternal.m */; };
6341807C1BBC103100F71761 /* ChatConversationCreateTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6341807B1BBC103100F71761 /* ChatConversationCreateTableView.m */; };
63423C0A1C4501D000D9A050 /* Contact.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423C091C4501D000D9A050 /* Contact.m */; };
634610061B61330300548952 /* UILabel+Boldify.m in Sources */ = {isa = PBXBuildFile; fileRef = 634610051B61330300548952 /* UILabel+Boldify.m */; };
6346100F1B61409800548952 /* CallOutgoingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6346100E1B61409800548952 /* CallOutgoingView.m */; };
634610121B6140A500548952 /* CallOutgoingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 634610101B6140A500548952 /* CallOutgoingView.xib */; };
......@@ -905,6 +906,8 @@
633E388219FFB0F400936D1C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
6341807A1BBC103100F71761 /* ChatConversationCreateTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatConversationCreateTableView.h; sourceTree = "<group>"; };
6341807B1BBC103100F71761 /* ChatConversationCreateTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatConversationCreateTableView.m; sourceTree = "<group>"; };
63423C081C4501D000D9A050 /* Contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Contact.h; sourceTree = "<group>"; };
63423C091C4501D000D9A050 /* Contact.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Contact.m; sourceTree = "<group>"; };
634610041B61330300548952 /* UILabel+Boldify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UILabel+Boldify.h"; sourceTree = "<group>"; };
634610051B61330300548952 /* UILabel+Boldify.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UILabel+Boldify.m"; sourceTree = "<group>"; };
6346100D1B61409800548952 /* CallOutgoingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallOutgoingView.h; sourceTree = "<group>"; };
......@@ -1378,7 +1381,6 @@
C9B3A6FD15B485DB006F52EE /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = Utils/Utils.h; sourceTree = "<group>"; };
D306459C1611EC2900BB571E /* UILoadingImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILoadingImageView.h; sourceTree = "<group>"; };
D306459D1611EC2900BB571E /* UILoadingImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILoadingImageView.m; sourceTree = "<group>"; };
D30BBD1215D3EFEB000F93DD /* ContactDetailsDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsDelegate.h; sourceTree = "<group>"; };
D30BF33216A427BC00AF0026 /* libtunnel.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtunnel.a; path = "liblinphone-sdk/apple-darwin/lib/libtunnel.a"; sourceTree = "<group>"; };
D3128FDE15AABC7E00A2147A /* ContactDetailsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsView.h; sourceTree = "<group>"; };
D3128FDF15AABC7E00A2147A /* ContactDetailsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailsView.m; sourceTree = "<group>"; };
......@@ -1760,7 +1762,6 @@
D35E7594159460560066B1C1 /* ChatsListView.h */,
D35E7595159460560066B1C1 /* ChatsListView.m */,
D38187B415FE340500C3EDCA /* ChatsListView.xib */,
D30BBD1215D3EFEB000F93DD /* ContactDetailsDelegate.h */,
D37C639915AADEF4009D0BAC /* ContactDetailsTableView.h */,
D37C639A15AADEF5009D0BAC /* ContactDetailsTableView.m */,
D3128FDE15AABC7E00A2147A /* ContactDetailsView.h */,
......@@ -2571,6 +2572,8 @@
D3554EC515CA79A900478841 /* XMLRPC.xcodeproj */,
63D11C521C3D501200E8FCEE /* Log.m */,
63D11C541C3D503A00E8FCEE /* Log.h */,
63423C081C4501D000D9A050 /* Contact.h */,
63423C091C4501D000D9A050 /* Contact.m */,
);
name = Utils;
sourceTree = "<group>";
......@@ -3414,6 +3417,7 @@
22AA8B0113D83F6300B30535 /* UICamSwitch.m in Sources */,
63B8D6A21BCBF43100C12B09 /* UIChatCreateCell.m in Sources */,
636BC9971B5F921B00C754CE /* UIIconButton.m in Sources */,
63423C0A1C4501D000D9A050 /* Contact.m in Sources */,
340751E7150F38FD00B89C47 /* UIVideoButton.m in Sources */,
34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */,
D3F83EEC1582021700336684 /* CallView.m in Sources */,
......
......@@ -10,5 +10,6 @@
#import "Log.h"
#import "Utils.h"
#import "UIToggleButton.h"
#import "UISpeakerButton.h"
#import "UIBluetoothButton.h"