From 12e82b9d22aa284ba043cc5ca1073e70358e914d Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Mon, 9 Jul 2012 16:22:29 +0200 Subject: [PATCH] Start Contact views Fix chat bug view bug (resize issue) --- Classes/ChatRoomTableViewController.h | 5 - Classes/ChatRoomTableViewController.m | 26 +- Classes/ChatRoomViewController.m | 5 +- Classes/ChatTableViewController.h | 5 - Classes/ChatTableViewController.m | 28 -- Classes/ChatViewController.m | 4 +- ....h => ContactDetailsTableViewController.h} | 18 +- Classes/ContactDetailsTableViewController.m | 208 ++++++++++ Classes/ContactDetailsViewController.h | 36 ++ Classes/ContactDetailsViewController.m | 70 ++++ Classes/ContactDetailsViewController.xib | 392 ++++++++++++++++++ Classes/ContactsTableViewController.h | 3 + Classes/ContactsTableViewController.m | 190 +++++---- Classes/ContactsViewController.m | 7 +- Classes/DialerViewController.h | 6 +- Classes/DialerViewController.m | 7 + Classes/HistoryTableViewController.h | 7 +- Classes/HistoryTableViewController.m | 96 +++-- Classes/HistoryViewController.m | 7 +- Classes/LinphoneManager.h | 4 + Classes/LinphoneManager.m | 72 ++++ Classes/LinphoneUI/UICallButton.m | 66 +-- Classes/LinphoneUI/UIChatCell.h | 2 - Classes/LinphoneUI/UIChatCell.m | 23 +- Classes/LinphoneUI/UIChatCell.xib | 24 +- Classes/LinphoneUI/UIChatRoomCell.h | 3 - Classes/LinphoneUI/UIChatRoomCell.m | 58 ++- Classes/LinphoneUI/UIChatRoomCell.xib | 2 +- Classes/LinphoneUI/UIChatRoomHeader.xib | 8 +- Classes/LinphoneUI/UIConferenceHeader.xib | 5 +- Classes/LinphoneUI/UIContactCell.h | 2 + Classes/LinphoneUI/UIContactCell.m | 17 +- Classes/LinphoneUI/UIContactCell.xib | 41 +- Classes/LinphoneUI/UIContactDetailsHeader.h | 39 ++ Classes/LinphoneUI/UIContactDetailsHeader.m | 81 ++++ Classes/LinphoneUI/UIContactDetailsHeader.xib | 244 +++++++++++ Classes/LinphoneUI/UIHistoryCell.h | 2 - Classes/LinphoneUI/UIHistoryCell.m | 30 +- Classes/LinphoneUI/UIHistoryCell.xib | 2 +- Classes/LinphoneUI/UIMainBar.m | 4 +- Classes/LinphoneUI/UIPauseResumeButton.m | 69 --- Classes/LinphoneUI/UITransferButton.m | 66 +-- Classes/Model/ChatModel.m | 2 +- Classes/PhoneMainView.h | 1 + Classes/PhoneMainView.m | 2 + Classes/Utils/FastAddressBook.m | 23 +- Resources/cancel_default.png | Bin 4152 -> 0 bytes Resources/cancel_over.png | Bin 4384 -> 0 bytes Resources/contact_back_default.png | Bin 0 -> 4647 bytes Resources/contact_back_over.png | Bin 0 -> 4368 bytes Resources/contact_edit_default.png | Bin 0 -> 4596 bytes Resources/contact_edit_over.png | Bin 0 -> 4284 bytes Resources/contact_number.png | Bin 0 -> 3673 bytes Resources/contact_number_over.png | Bin 0 -> 3584 bytes linphone.xcodeproj/project.pbxproj | 86 +++- 55 files changed, 1625 insertions(+), 473 deletions(-) rename Classes/{LinphoneUI/UIPauseResumeButton.h => ContactDetailsTableViewController.h} (73%) create mode 100644 Classes/ContactDetailsTableViewController.m create mode 100644 Classes/ContactDetailsViewController.h create mode 100644 Classes/ContactDetailsViewController.m create mode 100644 Classes/ContactDetailsViewController.xib create mode 100644 Classes/LinphoneUI/UIContactDetailsHeader.h create mode 100644 Classes/LinphoneUI/UIContactDetailsHeader.m create mode 100644 Classes/LinphoneUI/UIContactDetailsHeader.xib delete mode 100644 Classes/LinphoneUI/UIPauseResumeButton.m delete mode 100644 Resources/cancel_default.png delete mode 100644 Resources/cancel_over.png create mode 100644 Resources/contact_back_default.png create mode 100644 Resources/contact_back_over.png create mode 100644 Resources/contact_edit_default.png create mode 100644 Resources/contact_edit_over.png create mode 100644 Resources/contact_number.png create mode 100644 Resources/contact_number_over.png diff --git a/Classes/ChatRoomTableViewController.h b/Classes/ChatRoomTableViewController.h index 5256ce087..d118a363a 100644 --- a/Classes/ChatRoomTableViewController.h +++ b/Classes/ChatRoomTableViewController.h @@ -22,15 +22,10 @@ @interface ChatRoomTableViewController : UITableViewController { @private - BOOL editMode; NSArray *data; NSString *remoteContact; } @property (nonatomic, retain) NSString *remoteContact; -- (void) toggleEditMode; -- (void) enterEditMode; -- (void) exitEditMode; - @end diff --git a/Classes/ChatRoomTableViewController.m b/Classes/ChatRoomTableViewController.m index fa2250948..80f9a4ede 100644 --- a/Classes/ChatRoomTableViewController.m +++ b/Classes/ChatRoomTableViewController.m @@ -33,22 +33,14 @@ data = [[ChatModel listMessages:remoteContact] retain]; } -- (void) toggleEditMode { - editMode = !editMode; - [(UITableView*)[self view] reloadData]; + +#pragma mark - Property Functions + +- (void)setRemoteContact:(NSString *)aremoteContact { + self->remoteContact = aremoteContact; + [[self tableView] reloadData]; } -- (void) enterEditMode { - if(!editMode) { - [self toggleEditMode]; - } -} - -- (void) exitEditMode { - if(editMode) { - [self toggleEditMode]; - } -} #pragma mark - UITableViewDataSource Functions @@ -68,17 +60,13 @@ } [cell setChat:[data objectAtIndex:[indexPath row]]]; - if(editMode) - [cell enterEditMode]; - else - [cell exitEditMode]; [cell update]; return cell; } -#pragma mark - UITableViewelegate Functions +#pragma mark - UITableViewDelegate Functions - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { UIChatRoomHeader *headerController = [[UIChatRoomHeader alloc] init]; diff --git a/Classes/ChatRoomViewController.m b/Classes/ChatRoomViewController.m index d51977911..6be06c8e7 100644 --- a/Classes/ChatRoomViewController.m +++ b/Classes/ChatRoomViewController.m @@ -41,6 +41,7 @@ [tableController release]; [messageField release]; [sendButton release]; + [editButton release]; [super dealloc]; } @@ -83,7 +84,7 @@ name:@"LinphoneTextReceived" object:nil]; - [tableController exitEditMode]; + [[tableController tableView] setEditing:FALSE]; [editButton setOff]; [[tableController tableView] reloadData]; } @@ -179,7 +180,7 @@ } - (IBAction)onEditClick:(id)event { - [tableController toggleEditMode]; + [[tableController tableView] setEditing:![[tableController tableView] isEditing] animated:TRUE]; } - (IBAction)onSendClick:(id)event { diff --git a/Classes/ChatTableViewController.h b/Classes/ChatTableViewController.h index 9b5ca4c03..91965b7f6 100644 --- a/Classes/ChatTableViewController.h +++ b/Classes/ChatTableViewController.h @@ -21,12 +21,7 @@ @interface ChatTableViewController : UITableViewController { @private - BOOL editMode; NSArray *data; } -- (void) toggleEditMode; -- (void) enterEditMode; -- (void) exitEditMode; - @end diff --git a/Classes/ChatTableViewController.m b/Classes/ChatTableViewController.m index 287d881a1..769179480 100644 --- a/Classes/ChatTableViewController.m +++ b/Classes/ChatTableViewController.m @@ -28,13 +28,6 @@ #pragma mark - Lifecycle Functions -- (id)init { - if((self = [super init]) != nil) { - self->editMode = false; - } - return self; -} - - (void)dealloc { if(data != nil) [data release]; @@ -50,23 +43,6 @@ data = [[ChatModel listConversations] retain]; } -- (void) toggleEditMode { - editMode = !editMode; - [(UITableView*)[self view] reloadData]; -} - -- (void) enterEditMode { - if(!editMode) { - [self toggleEditMode]; - } -} - -- (void) exitEditMode { - if(editMode) { - [self toggleEditMode]; - } -} - #pragma mark - UITableViewDataSource Functions - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView @@ -88,10 +64,6 @@ } [cell setChat:[data objectAtIndex:[indexPath row]]]; - if(editMode) - [cell enterEditMode]; - else - [cell exitEditMode]; [cell update]; return cell; diff --git a/Classes/ChatViewController.m b/Classes/ChatViewController.m index 3e5279bca..8a92ae4b6 100644 --- a/Classes/ChatViewController.m +++ b/Classes/ChatViewController.m @@ -57,7 +57,7 @@ name:@"LinphoneTextReceived" object:nil]; - [tableController exitEditMode]; + [[tableController tableView] setEditing:FALSE]; [editButton setOff]; [[tableController tableView] reloadData]; } @@ -99,7 +99,7 @@ } - (IBAction)onEditClick:(id)event { - [tableController toggleEditMode]; + [[tableController tableView] setEditing:![[tableController tableView] isEditing] animated:TRUE]; } @end diff --git a/Classes/LinphoneUI/UIPauseResumeButton.h b/Classes/ContactDetailsTableViewController.h similarity index 73% rename from Classes/LinphoneUI/UIPauseResumeButton.h rename to Classes/ContactDetailsTableViewController.h index fe5a80e30..955868e99 100644 --- a/Classes/LinphoneUI/UIPauseResumeButton.h +++ b/Classes/ContactDetailsTableViewController.h @@ -1,6 +1,6 @@ -/* UIMuteButton.h +/* ContactDetailsTableViewController.h * - * Copyright (C) 2011 Belledonne Comunications, Grenoble, France + * 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 @@ -15,14 +15,18 @@ * 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. - */ + */ #import -#import "UIToggleButton.h" - - -@interface UIPauseResumeButton : UIToggleButton { +#import +@interface ContactDetailsTableViewController : UITableViewController { +@private + ABRecordRef contact; + NSMutableArray *dataCache; + ABAddressBookRef addressBook; } +@property (nonatomic, assign) ABRecordRef contact; + @end diff --git a/Classes/ContactDetailsTableViewController.m b/Classes/ContactDetailsTableViewController.m new file mode 100644 index 000000000..d8f355650 --- /dev/null +++ b/Classes/ContactDetailsTableViewController.m @@ -0,0 +1,208 @@ +/* ContactDetailsTableViewController.m + * + * 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. + */ + +#import "ContactDetailsTableViewController.h" +#import "UIContactDetailsHeader.h" +#import "PhoneMainView.h" + +@implementation ContactDetailsTableViewController + +@synthesize contact; + + +#pragma mark - Lifecycle Functions + +- (void)initContactDetailsTableViewController { + addressBook = ABAddressBookCreate(); + dataCache = [[NSMutableArray alloc] init]; +} + +- (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; +} + +- (void)dealloc { + [dataCache dealloc]; + [super dealloc]; +} + + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + ABAddressBookRegisterExternalChangeCallback (addressBook, sync_toc_address_book, self); +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_toc_address_book, self); +} + + +#pragma mark - + +static void sync_toc_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) { + ContactDetailsTableViewController* controller = (ContactDetailsTableViewController*)context; + ABRecordID recordID = ABRecordGetRecordID([controller contact]); + ABRecordRef newRecord = ABAddressBookGetPersonWithRecordID(addressBook, recordID); + if(newRecord) { + [controller setContact:newRecord]; + } +} + +- (void)loadData { + [dataCache removeAllObjects]; + + if(contact == NULL) + return; + + // Phone numbers + { + ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty); + NSMutableArray *subArray = [[NSMutableArray alloc] init]; + for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) { + CFStringRef lValue = ABMultiValueCopyValueAtIndex(lMap, i); + CFStringRef lLabel = ABMultiValueCopyLabelAtIndex(lMap, i); + CFStringRef lLocalizedLabel = ABAddressBookCopyLocalizedLabel(lLabel); + [subArray addObject:[NSArray arrayWithObjects:[NSString stringWithString:(NSString*)lValue], [NSString stringWithString:(NSString*)lLocalizedLabel], nil]]; + if(lLocalizedLabel) + CFRelease(lLocalizedLabel); + CFRelease(lLabel); + CFRelease(lValue); + } + [dataCache addObject:subArray]; + CFRelease(lMap); + } + + // SIP (IM) + { + ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); + NSMutableArray *subArray = [[NSMutableArray alloc] init]; + for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) { + CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i); + if(CFDictionaryContainsKey(lDict, @"service")) { + if(CFStringCompare((CFStringRef)@"SIP", CFDictionaryGetValue(lDict, @"service"), kCFCompareCaseInsensitive) == 0) { + CFStringRef lValue = CFDictionaryGetValue(lDict, @"username"); + CFStringRef lLabel = ABMultiValueCopyLabelAtIndex(lMap, i); + CFStringRef lLocalizedLabel = ABAddressBookCopyLocalizedLabel(lLabel); + [subArray addObject:[NSArray arrayWithObjects:[NSString stringWithString:(NSString*)lValue], [NSString stringWithString:(NSString*)lLocalizedLabel], nil]]; + if(lLocalizedLabel) + CFRelease(lLocalizedLabel); + CFRelease(lLabel); + + } + } + CFRelease(lDict); + } + [dataCache addObject:subArray]; + CFRelease(lMap); + } +} + + +#pragma mark - Property Functions + +- (void)setContact:(ABRecordRef)acontact { + self->contact = acontact; + [[self tableView] reloadData]; +} + + +#pragma mark - UITableViewDataSource Functions + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + [self loadData]; + return [dataCache count]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + NSMutableDictionary *dict = [dataCache objectAtIndex:section]; + return [dict count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ContactDetailsCell"]; + if (cell == nil) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:@"ContactDetailsCell"]; + //[cell setSelectedBackgroundView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"list_hightlight.png"]]]; + } + NSMutableArray *sectionDict = [dataCache objectAtIndex:[indexPath section]]; + NSArray *tuple = [sectionDict objectAtIndex:[indexPath row]]; + [cell.textLabel setText:[tuple objectAtIndex:1]]; + [cell.detailTextLabel setText:[tuple objectAtIndex:0]]; + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + NSMutableArray *sectionDict = [dataCache objectAtIndex:[indexPath section]]; + NSArray *tuple = [sectionDict objectAtIndex:[indexPath row]]; + + NSString *dest = [tuple objectAtIndex:0]; + if(![dest hasPrefix:@"sip:"]) + dest = [NSString stringWithFormat:@"sip:%@", [tuple objectAtIndex:0]]; + CFStringRef lDisplayName = ABRecordCopyCompositeName(contact); + NSString *displayName = [NSString stringWithString:(NSString*) lDisplayName]; + CFRelease(lDisplayName); + + // Go to dialer view + NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: + [[[NSArray alloc] initWithObjects: dest, displayName, nil] autorelease] + , @"call:displayName:", + nil] autorelease]; + [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; +} + + +#pragma mark - UITableViewDelegate Functions + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { + if(section == 0) { + UIContactDetailsHeader *headerController = [[UIContactDetailsHeader alloc] init]; + UIView *headerView = [headerController view]; + [headerController setContact:contact]; + [headerController update]; + [headerController release]; + return headerView; + } else { + return [[UIView alloc] initWithFrame:CGRectZero]; + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { + if(section == 0) + return [UIContactDetailsHeader height]; + else { + return 0.000001f; // Hack UITableView = 0 + } +} + +@end diff --git a/Classes/ContactDetailsViewController.h b/Classes/ContactDetailsViewController.h new file mode 100644 index 000000000..bf50a77b3 --- /dev/null +++ b/Classes/ContactDetailsViewController.h @@ -0,0 +1,36 @@ +/* ContactDetailsViewController.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. + */ + +#import +#import + +#import "UICompositeViewController.h" +#import "ContactDetailsTableViewController.h" + +@interface ContactDetailsViewController : UIViewController { + ContactDetailsTableViewController *tableController; + ABRecordRef contact; +} + +@property (nonatomic, assign) ABRecordRef contact; +@property (nonatomic, retain) IBOutlet ContactDetailsTableViewController *tableController; + +- (IBAction)onBackClick:(id)event; + +@end diff --git a/Classes/ContactDetailsViewController.m b/Classes/ContactDetailsViewController.m new file mode 100644 index 000000000..c025949a1 --- /dev/null +++ b/Classes/ContactDetailsViewController.m @@ -0,0 +1,70 @@ +/* ContactDetailsViewController.m + * + * 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. + */ + +#import "ContactDetailsViewController.h" +#import "PhoneMainView.h" + +@implementation ContactDetailsViewController + +@synthesize tableController; +@synthesize contact; + +#pragma mark - Lifecycle Functions + +- (id)init { + return [super initWithNibName:@"ContactDetailsViewController" bundle:[NSBundle mainBundle]]; +} + +- (void)dealloc { + [tableController release]; + + [super dealloc]; +} + + +#pragma mark - Property Functions + + +- (void)setContact:(ABRecordRef)acontact { + self->contact = acontact; + [tableController setContact:contact]; +} + + +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription*) compositeViewDescription { + UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"ContactDetailsViewController"; + description->tabBar = @"UIMainBar"; + description->tabBarEnabled = true; + description->stateBar = nil; + description->stateBarEnabled = false; + description->fullscreen = false; + return description; +} + + +#pragma mark - Action Functions + +- (IBAction)onBackClick:(id)event { + [[PhoneMainView instance] popView]; +} + +@end diff --git a/Classes/ContactDetailsViewController.xib b/Classes/ContactDetailsViewController.xib new file mode 100644 index 000000000..91f6d8dd2 --- /dev/null +++ b/Classes/ContactDetailsViewController.xib @@ -0,0 +1,392 @@ + + + + 1296 + 11E53 + 2182 + 1138.47 + 569.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1181 + + + IBUITableViewController + IBUIButton + IBUIImageView + IBUIView + IBUITableView + IBProxyObject + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + + + + 292 + {320, 460} + + + + _NS:9 + NO + IBCocoaTouchFramework + + NSImage + numpad_background.png + + + + + 290 + + + + 292 + {160, 58} + + + + _NS:9 + NO + + Add contact + + IBCocoaTouchFramework + 0 + 0 + NO + + 3 + MC41AA + + + NSImage + contact_back_over.png + + + NSImage + contact_back_default.png + + + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + + + + 292 + {{160, 0}, {160, 58}} + + + + _NS:9 + NO + + Add contact + + IBCocoaTouchFramework + 0 + 0 + NO + + + NSImage + contact_edit_over.png + + + NSImage + contact_edit_default.png + + + + + + {320, 58} + + + + _NS:9 + + 3 + MQA + + 2 + + + IBCocoaTouchFramework + + + + 306 + {{0, 59}, {320, 401}} + + + + _NS:9 + + 3 + MCAwAA + + YES + IBCocoaTouchFramework + YES + 1 + 2 + 0 + YES + 44 + 10 + 10 + + + {{0, 20}, {320, 460}} + + + + + 3 + MQA + + + + IBCocoaTouchFramework + + + + + 1 + 1 + + IBCocoaTouchFramework + NO + + + + + + + view + + + + 3 + + + + tableController + + + + 27 + + + + onBackClick: + + + 7 + + 10 + + + + dataSource + + + + 28 + + + + delegate + + + + 29 + + + + view + + + + 26 + + + + + + 0 + + + + + + 1 + + + + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + header + + + 8 + + + editButton + + + 9 + + + backButton + + + 11 + + + background + + + 19 + + + tableView + + + 20 + + + + tableController + + + + + ContactDetailsViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + ContactDetailsTableViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + + 29 + + + + + ContactDetailsTableViewController + UITableViewController + + IBProjectSource + ./Classes/ContactDetailsTableViewController.h + + + + ContactDetailsViewController + UIViewController + + onBackClick: + id + + + onBackClick: + + onBackClick: + id + + + + tableController + ContactDetailsTableViewController + + + tableController + + tableController + ContactDetailsTableViewController + + + + IBProjectSource + ./Classes/ContactDetailsViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + YES + 3 + + {320, 117} + {320, 117} + {320, 117} + {320, 117} + {640, 523} + + 1181 + + diff --git a/Classes/ContactsTableViewController.h b/Classes/ContactsTableViewController.h index 696b0ef7e..7ae506cb8 100644 --- a/Classes/ContactsTableViewController.h +++ b/Classes/ContactsTableViewController.h @@ -26,6 +26,9 @@ OrderedDictionary* addressBookMap; ABAddressBookRef addressBook; + BOOL sipFilter; } +@property (nonatomic, assign) BOOL sipFilter; + @end diff --git a/Classes/ContactsTableViewController.m b/Classes/ContactsTableViewController.m index f67ce8f71..643fbb361 100644 --- a/Classes/ContactsTableViewController.m +++ b/Classes/ContactsTableViewController.m @@ -24,67 +24,129 @@ @implementation ContactsTableViewController -void sync_toc_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) { - ContactsTableViewController* controller = (ContactsTableViewController*)context; - OrderedDictionary* lAddressBookMap = controller->addressBookMap; - @synchronized (lAddressBookMap) { - - // Reset Address book - - [lAddressBookMap removeAllObjects]; - - NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); - for (id lPerson in lContacts) { - CFStringRef lFirstName = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonFirstNameProperty); - CFStringRef lLocalizedFirstName = (lFirstName != nil)? ABAddressBookCopyLocalizedLabel(lFirstName): nil; - CFStringRef lLastName = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonLastNameProperty); - CFStringRef lLocalizedLastName = (lLastName != nil)? ABAddressBookCopyLocalizedLabel(lLastName): nil; - NSString *name = nil; - if(lLocalizedFirstName != nil && lLocalizedLastName != nil) { - name=[NSString stringWithFormat:@"%@%@", [(NSString *)lLocalizedFirstName retain], [(NSString *)lLocalizedLastName retain]]; - } else if(lLocalizedLastName != nil) { - name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedLastName retain]]; - } else if(lLocalizedFirstName != nil) { - name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedFirstName retain]]; - } - if(name != nil) { - // Put in correct subDic - NSString *firstChar = [[name substringToIndex:1] uppercaseString]; - OrderedDictionary *subDic =[lAddressBookMap objectForKey: firstChar]; - if(subDic == nil) { - subDic = [[OrderedDictionary alloc] init]; - [lAddressBookMap insertObject:subDic forKey:firstChar selector:@selector(caseInsensitiveCompare:)]; - } - [subDic insertObject:lPerson forKey:name selector:@selector(caseInsensitiveCompare:)]; - } - if(lLocalizedLastName != nil) - CFRelease(lLocalizedLastName); - if(lLastName != nil) - CFRelease(lLastName); - if(lLocalizedFirstName != nil) - CFRelease(lLocalizedFirstName); - if(lFirstName != nil) - CFRelease(lFirstName); - } - CFRelease(lContacts); +@synthesize sipFilter; + +#pragma mark - Lifecycle Functions + +- (void)initContactsTableViewController { + addressBookMap = [[OrderedDictionary alloc] init]; + addressBook = ABAddressBookCreate(); +} + +- (id)init { + self = [super init]; + if (self) { + [self initContactsTableViewController]; } + return self; +} + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + [self initContactsTableViewController]; + } + return self; +} + +- (void)dealloc { + [super dealloc]; + [addressBookMap removeAllObjects]; +} + + +#pragma mark - Property Functions + +- (void)setSipFilter:(BOOL)asipFilter { + self->sipFilter = asipFilter; + [[self tableView] reloadData]; +} + + +#pragma mark - + +static void sync_toc_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) { + ContactsTableViewController* controller = (ContactsTableViewController*)context; [(UITableView *)controller.view reloadData]; } #pragma mark - ViewController Functions -- (void) viewDidLoad { - addressBookMap = [[OrderedDictionary alloc] init]; - addressBook = ABAddressBookCreate(); +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; ABAddressBookRegisterExternalChangeCallback (addressBook, sync_toc_address_book, self); - sync_toc_address_book(addressBook, nil, self); +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_toc_address_book, self); } #pragma mark - UITableViewDataSource Functions +- (void)reloadData { + @synchronized (addressBookMap) { + + // Reset Address book + [addressBookMap removeAllObjects]; + + NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); + for (id lPerson in lContacts) { + BOOL add = true; + if(sipFilter) { + add = false; + ABMultiValueRef lMap = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonInstantMessageProperty); + for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) { + CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i); + if(CFDictionaryContainsKey(lDict, @"service")) { + if(CFStringCompare((CFStringRef)@"SIP", CFDictionaryGetValue(lDict, @"service"), kCFCompareCaseInsensitive) == 0) { + add = true; + } + } + CFRelease(lDict); + } + } + if(add) { + CFStringRef lFirstName = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonFirstNameProperty); + CFStringRef lLocalizedFirstName = (lFirstName != nil)? ABAddressBookCopyLocalizedLabel(lFirstName): nil; + CFStringRef lLastName = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonLastNameProperty); + CFStringRef lLocalizedLastName = (lLastName != nil)? ABAddressBookCopyLocalizedLabel(lLastName): nil; + NSString *name = nil; + if(lLocalizedFirstName != nil && lLocalizedLastName != nil) { + name=[NSString stringWithFormat:@"%@%@", [(NSString *)lLocalizedFirstName retain], [(NSString *)lLocalizedLastName retain]]; + } else if(lLocalizedLastName != nil) { + name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedLastName retain]]; + } else if(lLocalizedFirstName != nil) { + name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedFirstName retain]]; + } + if(name != nil) { + // Put in correct subDic + NSString *firstChar = [[name substringToIndex:1] uppercaseString]; + 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:)]; + } + if(lLocalizedLastName != nil) + CFRelease(lLocalizedLastName); + if(lLastName != nil) + CFRelease(lLastName); + if(lLocalizedFirstName != nil) + CFRelease(lLocalizedFirstName); + if(lFirstName != nil) + CFRelease(lFirstName); + } + } + CFRelease(lContacts); + } +} + - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + [self reloadData]; return [addressBookMap count]; } @@ -115,35 +177,13 @@ void sync_toc_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { OrderedDictionary *subDic = [addressBookMap objectForKey: [addressBookMap keyAtIndex: [indexPath section]]]; ABRecordRef lPerson = [subDic objectForKey: [subDic keyAtIndex:[indexPath row]]]; - // TODO - ABMultiValueRef lPhoneNumbers = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonPhoneProperty); - for(CFIndex i = 0; i < ABMultiValueGetCount(lPhoneNumbers); i++) { - CFStringRef lLabel = ABMultiValueCopyLabelAtIndex(lPhoneNumbers, i); - if ([(NSString*)lLabel isEqualToString:(NSString*)kABPersonPhoneMainLabel]) { - CFStringRef lNumber = ABMultiValueCopyValueAtIndex(lPhoneNumbers,i); - NSString *number = [(NSString *)lNumber retain]; - - // Go to dialer view - NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: number, nil] autorelease] - , @"setAddress:", - nil] autorelease]; - [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; - - CFRelease(lNumber); - break; - } - CFRelease(lLabel); - } - CFRelease(lPhoneNumbers); -} - -#pragma mark - Lifecycle Functions - -- (void)dealloc { - [super dealloc]; - [addressBookMap removeAllObjects]; + // Go to Contact details view + NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: + [[[NSArray alloc] initWithObjects: lPerson, nil] autorelease] + , @"setContact:", + nil] autorelease]; + [[PhoneMainView instance] changeView:PhoneView_ContactDetails dict:dict push:TRUE]; } @end diff --git a/Classes/ContactsViewController.m b/Classes/ContactsViewController.m index 1bfd43ea6..add579a53 100644 --- a/Classes/ContactsViewController.m +++ b/Classes/ContactsViewController.m @@ -35,6 +35,7 @@ typedef enum _HistoryView { History_MAX } HistoryView; + #pragma mark - Lifecycle Functions - (id)init { @@ -70,7 +71,7 @@ typedef enum _HistoryView { - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; - [self.tableView reloadData]; + [self changeView:History_All]; } - (void)viewDidLoad { @@ -91,18 +92,22 @@ typedef enum _HistoryView { - (void)changeView: (HistoryView) view { if(view == History_All) { + + [tableController setSipFilter:FALSE]; allButton.selected = TRUE; } else { allButton.selected = FALSE; } if(view == History_Linphone) { + [tableController setSipFilter:TRUE]; linphoneButton.selected = TRUE; } else { linphoneButton.selected = FALSE; } } + #pragma mark - Action Functions - (IBAction)onAllClick: (id) event { diff --git a/Classes/DialerViewController.h b/Classes/DialerViewController.h index 8a90e2b63..2eedfca28 100644 --- a/Classes/DialerViewController.h +++ b/Classes/DialerViewController.h @@ -54,8 +54,10 @@ BOOL transferMode; } -- (void)setAddress:(NSString*) address; -- (void)setTransferMode:(NSNumber*) enable; +- (void)setAddress:(NSString*)address; +- (void)setTransferMode:(NSNumber*)enable; +- (void)call:(NSString*)address displayName:(NSString *)displayName; +- (void)call:(NSString*)address; @property (nonatomic, retain) IBOutlet UITextField* addressField; @property (nonatomic, retain) IBOutlet UIButton* addContactButton; diff --git a/Classes/DialerViewController.m b/Classes/DialerViewController.m index df5cf434e..2d3c3f250 100644 --- a/Classes/DialerViewController.m +++ b/Classes/DialerViewController.m @@ -193,6 +193,13 @@ [self callUpdate:call state:state]; } +- (void)call:(NSString*)address { + [self call:address displayName:nil]; +} + +- (void)call:(NSString*)address displayName:(NSString *)displayName { + [[LinphoneManager instance] call:address displayName:displayName transfer:transferMode]; +} #pragma mark - UITextFieldDelegate Functions diff --git a/Classes/HistoryTableViewController.h b/Classes/HistoryTableViewController.h index 09f55b9e7..9b2dc7aef 100644 --- a/Classes/HistoryTableViewController.h +++ b/Classes/HistoryTableViewController.h @@ -21,11 +21,10 @@ @interface HistoryTableViewController : UITableViewController { @private - BOOL editMode; + BOOL missedFilter; + NSMutableArray *callLogs; } -- (void) toggleEditMode; -- (void) enterEditMode; -- (void) exitEditMode; +@property (nonatomic, assign) BOOL missedFilter; @end diff --git a/Classes/HistoryTableViewController.m b/Classes/HistoryTableViewController.m index 99c18004e..15f4bba32 100644 --- a/Classes/HistoryTableViewController.m +++ b/Classes/HistoryTableViewController.m @@ -24,26 +24,70 @@ @implementation HistoryTableViewController +@synthesize missedFilter; #pragma mark - Lifecycle Functions +- (void)initHistoryTableViewController { + callLogs = [[NSMutableArray alloc] init]; + missedFilter = false; +} + - (id)init { - if((self = [super init]) != nil) { - self->editMode = false; + self = [super init]; + if (self) { + [self initHistoryTableViewController]; } return self; } +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + [self initHistoryTableViewController]; + } + return self; +} + +- (void)dealloc { + [callLogs release]; + [super dealloc]; +} + + +#pragma mark - Property Functions + +- (void)setMissedFilter:(BOOL)amissedFilter { + self->missedFilter = amissedFilter; + [[self tableView] reloadData]; +} + #pragma mark - UITableViewDataSource Functions +- (void)loadData { + [callLogs removeAllObjects]; + const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]); + while(logs != NULL) { + LinphoneCallLog* log = (LinphoneCallLog *) logs->data; + if(missedFilter) { + if (log->status == LinphoneCallMissed) { + [callLogs addObject:[NSValue valueWithPointer: log]]; + } + } else { + [callLogs addObject:[NSValue valueWithPointer: log]]; + } + logs = ms_list_next(logs); + } +} + - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]); - return ms_list_size(logs); + [self loadData]; + return [callLogs count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { @@ -52,15 +96,8 @@ cell = [[UIHistoryCell alloc] initWithIdentifier:@"UIHistoryCell"]; } - const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]); - LinphoneCallLog* callLogs = ms_list_nth_data(logs, indexPath.row); - - if(editMode) - [cell enterEditMode]; - else - [cell exitEditMode]; - - [cell setCallLog:callLogs]; + LinphoneCallLog *log = [[callLogs objectAtIndex:[indexPath row]] pointerValue]; + [cell setCallLog:log]; [cell update]; return cell; @@ -72,13 +109,12 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:NO]; - const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]); - LinphoneCallLog* callLogs = ms_list_nth_data(logs, indexPath.row) ; + LinphoneCallLog *log = [[callLogs objectAtIndex:[indexPath row]] pointerValue]; LinphoneAddress* partyToCall; - if (callLogs->dir == LinphoneCallIncoming) { - partyToCall=callLogs->from; + if (log->dir == LinphoneCallIncoming) { + partyToCall=log->from; } else { - partyToCall=callLogs->to; + partyToCall=log->to; } const char* username = linphone_address_get_username(partyToCall)!=0?linphone_address_get_username(partyToCall):""; const char* displayName = linphone_address_get_display_name(partyToCall)!=0?linphone_address_get_display_name(partyToCall):""; @@ -99,8 +135,8 @@ // Go to dialer view NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: phoneNumber, nil] autorelease] - , @"setAddress:", + [[[NSArray alloc] initWithObjects: phoneNumber, dispName, nil] autorelease] + , @"call:displayName:", nil] autorelease]; [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; @@ -108,25 +144,5 @@ [dispName release]; } - -#pragma mark - - -- (void) toggleEditMode { - editMode = !editMode; - [(UITableView*)[self view] reloadData]; -} - -- (void) enterEditMode { - if(!editMode) { - [self toggleEditMode]; - } -} - -- (void) exitEditMode { - if(editMode) { - [self toggleEditMode]; - } -} - @end diff --git a/Classes/HistoryViewController.m b/Classes/HistoryViewController.m index 6faf08aa8..f60c676ac 100644 --- a/Classes/HistoryViewController.m +++ b/Classes/HistoryViewController.m @@ -70,7 +70,8 @@ typedef enum _HistoryView { - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; - [tableController exitEditMode]; + [[tableController tableView] setEditing:FALSE]; + [self changeView: History_All]; [editButton setOff]; [self.tableView reloadData]; } @@ -98,12 +99,14 @@ typedef enum _HistoryView { - (void)changeView: (HistoryView) view { if(view == History_All) { allButton.selected = TRUE; + [tableController setMissedFilter:FALSE]; } else { allButton.selected = FALSE; } if(view == History_Missed) { missedButton.selected = TRUE; + [tableController setMissedFilter:TRUE]; } else { missedButton.selected = FALSE; } @@ -121,7 +124,7 @@ typedef enum _HistoryView { } - (IBAction)onEditClick:(id) event { - [tableController toggleEditMode]; + [[tableController tableView] setEditing:![[tableController tableView] isEditing] animated:TRUE]; } diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index 7328d6df2..1b7a54a21 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -57,6 +57,7 @@ typedef struct _LinphoneCallAppData { @interface LinphoneManager : NSObject { @protected SCNetworkReachabilityRef proxyReachability; + @private NSTimer* mIterateTimer; id mLogView; @@ -82,6 +83,9 @@ typedef struct _LinphoneCallAppData { + (NSString *)getPreferenceForCodec: (const char*) name withRate: (int) rate; + (BOOL)codecIsSupported:(NSString *) prefName; + +- (void)call:(NSString *)address displayName:(NSString*)displayName transfer:(BOOL)transfer; + - (void)startLibLinphone; - (BOOL)isNotIphone3G; - (void)destroyLibLinphone; diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 3bac80534..b7396a70c 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -25,6 +25,7 @@ #import #import #import +#import #import "LinphoneManager.h" #import "FastAddressBook.h" @@ -363,6 +364,7 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo [chat setRemoteContact:[NSString stringWithUTF8String:linphone_address_get_username(from)]]; [chat setMessage:[NSString stringWithUTF8String:message]]; [chat setDirection:[NSNumber numberWithInt:1]]; + [chat setTime:[NSDate date]]; [chat create]; // Post event @@ -820,4 +822,74 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach return NO; } + +- (void)call:(NSString *)address displayName:(NSString*)displayName transfer:(BOOL)transfer { + if (!linphone_core_is_network_reachabled(theLinphoneCore)) { + UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Network Error",nil) + message:NSLocalizedString(@"There is no network connection available, enable WIFI or WWAN prior to place a call",nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue",nil) + otherButtonTitles:nil]; + [error show]; + [error release]; + return; + } + + CTCallCenter* ct = [[CTCallCenter alloc] init]; + if ([ct.currentCalls count] > 0) { + ms_error("GSM call in progress, cancelling outgoing SIP call request"); + UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot make call",nil) + message:NSLocalizedString(@"Please terminate GSM call",nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue",nil) + otherButtonTitles:nil]; + [error show]; + [error release]; + [ct release]; + return; + } + [ct release]; + + LinphoneProxyConfig* proxyCfg; + //get default proxy + linphone_core_get_default_proxy([LinphoneManager getLc],&proxyCfg); + LinphoneCallParams* lcallParams = linphone_core_create_default_call_parameters([LinphoneManager getLc]); + + if ([address length] == 0) return; //just return + if ([address hasPrefix:@"sip:"]) { + LinphoneAddress* linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]); + if(displayName!=nil) { + linphone_address_set_display_name(linphoneAddress,[displayName cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } + if(transfer) { + linphone_core_transfer_call([LinphoneManager getLc], linphone_core_get_current_call([LinphoneManager getLc]), [address cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } else { + linphone_core_invite_address_with_params([LinphoneManager getLc], linphoneAddress, lcallParams); + } + linphone_address_destroy(linphoneAddress); + } else if ( proxyCfg==nil){ + UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid sip address",nil) + message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to place a call or use a valid sip address (I.E sip:john@example.net)",nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue",nil) + otherButtonTitles:nil]; + [error show]; + [error release]; + } else { + char normalizedUserName[256]; + LinphoneAddress* linphoneAddress = linphone_address_new(linphone_core_get_identity([LinphoneManager getLc])); + linphone_proxy_config_normalize_number(proxyCfg,[address cStringUsingEncoding:[NSString defaultCStringEncoding]],normalizedUserName,sizeof(normalizedUserName)); + linphone_address_set_username(linphoneAddress, normalizedUserName); + if(displayName!=nil) { + linphone_address_set_display_name(linphoneAddress,[displayName cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } + if(transfer) { + linphone_core_transfer_call([LinphoneManager getLc], linphone_core_get_current_call([LinphoneManager getLc]), normalizedUserName); + } else { + linphone_core_invite_address_with_params([LinphoneManager getLc], linphoneAddress,lcallParams); + } + } + linphone_call_params_destroy(lcallParams); +} + @end diff --git a/Classes/LinphoneUI/UICallButton.m b/Classes/LinphoneUI/UICallButton.m index 12d647da7..b34ff5e1b 100644 --- a/Classes/LinphoneUI/UICallButton.m +++ b/Classes/LinphoneUI/UICallButton.m @@ -62,71 +62,11 @@ [super dealloc]; } + #pragma mark - --(void) touchUp:(id) sender { - if (!linphone_core_is_network_reachabled([LinphoneManager getLc])) { - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Network Error",nil) - message:NSLocalizedString(@"There is no network connection available, enable WIFI or WWAN prior to place a call",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - return; - } - - CTCallCenter* ct = [[CTCallCenter alloc] init]; - if ([ct.currentCalls count] > 0) { - ms_error("GSM call in progress, cancelling outgoing SIP call request"); - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot make call",nil) - message:NSLocalizedString(@"Please terminate GSM call",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - [ct release]; - return; - } - [ct release]; - - if (TRUE /*!linphone_core_in_call([LinphoneManager getLc])*/) { - LinphoneProxyConfig* proxyCfg; - //get default proxy - linphone_core_get_default_proxy([LinphoneManager getLc],&proxyCfg); - LinphoneCallParams* lcallParams = linphone_core_create_default_call_parameters([LinphoneManager getLc]); - - if ([addressField.text length] == 0) return; //just return - if ([addressField.text hasPrefix:@"sip:"]) { - linphone_core_invite_with_params([LinphoneManager getLc],[addressField.text cStringUsingEncoding:[NSString defaultCStringEncoding]],lcallParams); - } else if ( proxyCfg==nil){ - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid sip address",nil) - message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to place a call or use a valid sip address (I.E sip:john@example.net)",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - } else { - char normalizedUserName[256]; - NSString* toUserName = [NSString stringWithString:[addressField text]]; - NSString* lDisplayName = [[LinphoneManager instance] getDisplayNameFromAddressBook:toUserName andUpdateCallLog:nil]; - - linphone_proxy_config_normalize_number(proxyCfg,[toUserName cStringUsingEncoding:[NSString defaultCStringEncoding]],normalizedUserName,sizeof(normalizedUserName)); - LinphoneAddress* tmpAddress = linphone_address_new(linphone_core_get_identity([LinphoneManager getLc])); - linphone_address_set_username(tmpAddress,normalizedUserName); - linphone_address_set_display_name(tmpAddress,(lDisplayName)?[lDisplayName cStringUsingEncoding:[NSString defaultCStringEncoding]]:nil); - - - linphone_core_invite_address_with_params([LinphoneManager getLc],tmpAddress,lcallParams) ; - - linphone_address_destroy(tmpAddress); - } - linphone_call_params_destroy(lcallParams); - } else if (linphone_core_inc_invite_pending([LinphoneManager getLc])) { - linphone_core_accept_call([LinphoneManager getLc],linphone_core_get_current_call([LinphoneManager getLc])); - } +- (void)touchUp:(id) sender { + [[LinphoneManager instance] call:[addressField text] displayName:nil transfer:FALSE]; } @end diff --git a/Classes/LinphoneUI/UIChatCell.h b/Classes/LinphoneUI/UIChatCell.h index 9fdb9f7af..d66e7bfad 100644 --- a/Classes/LinphoneUI/UIChatCell.h +++ b/Classes/LinphoneUI/UIChatCell.h @@ -40,8 +40,6 @@ - (id)initWithIdentifier:(NSString*)identifier; - (void)update; -- (void)enterEditMode; -- (void)exitEditMode; - (IBAction)onDetailsClick:(id)event; - (IBAction)onDeleteClick:(id)event; diff --git a/Classes/LinphoneUI/UIChatCell.m b/Classes/LinphoneUI/UIChatCell.m index aa1969582..5b97b2738 100644 --- a/Classes/LinphoneUI/UIChatCell.m +++ b/Classes/LinphoneUI/UIChatCell.m @@ -91,14 +91,25 @@ [chatContentLabel setFrame: chatContentFrame]; } -- (void)enterEditMode { - [deleteButton setHidden:false]; - [detailsButton setHidden:true]; +- (void)setEditing:(BOOL)editing { + [self setEditing:editing animated:FALSE]; } -- (void)exitEditMode { - [detailsButton setHidden:false]; - [deleteButton setHidden:true]; +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + if(animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + } + if(editing) { + [deleteButton setAlpha:1.0f]; + [detailsButton setAlpha:0.0f]; + } else { + [detailsButton setAlpha:1.0f]; + [deleteButton setAlpha:0.0f]; + } + if(animated) { + [UIView commitAnimations]; + } } #pragma mark - Action Functions diff --git a/Classes/LinphoneUI/UIChatCell.xib b/Classes/LinphoneUI/UIChatCell.xib index f8738e424..9d6d04987 100644 --- a/Classes/LinphoneUI/UIChatCell.xib +++ b/Classes/LinphoneUI/UIChatCell.xib @@ -127,7 +127,6 @@ {{276, 0}, {44, 44}} - _NS:9 NO IBCocoaTouchFramework @@ -162,7 +161,7 @@ - -2147483356 + 292 {{276, 0}, {44, 44}} @@ -206,7 +205,6 @@ {320, 44} - _NS:9 NO IBCocoaTouchFramework @@ -221,7 +219,6 @@ {320, 44} - _NS:9 NO @@ -409,17 +406,20 @@ UIChatCell UITableViewCell - - onDetailsClick: - id - - - onDetailsClick: - + + id + id + + + + onDeleteClick: + id + + onDetailsClick: id - + UIImageView UILabel diff --git a/Classes/LinphoneUI/UIChatRoomCell.h b/Classes/LinphoneUI/UIChatRoomCell.h index abc320f0f..113bf0bd1 100644 --- a/Classes/LinphoneUI/UIChatRoomCell.h +++ b/Classes/LinphoneUI/UIChatRoomCell.h @@ -41,9 +41,6 @@ - (void)update; -- (void)enterEditMode; -- (void)exitEditMode; - - (IBAction)onDeleteClick:(id)event; @end diff --git a/Classes/LinphoneUI/UIChatRoomCell.m b/Classes/LinphoneUI/UIChatRoomCell.m index 5f77fc7a8..0ee530fbd 100644 --- a/Classes/LinphoneUI/UIChatRoomCell.m +++ b/Classes/LinphoneUI/UIChatRoomCell.m @@ -61,6 +61,40 @@ static UIFont *CELL_FONT = nil; #pragma mark - - (void)update { + if(chat != nil) { + [messageLabel setText:[chat message]]; + } +} + +- (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(editing) { + [deleteButton setAlpha:1.0f]; + } else { + [deleteButton setAlpha:0.0f]; + } + if(animated) { + [UIView commitAnimations]; + } +} + +- (void)resizeContent { + // Resize content + { + CGRect frame = [contentView frame]; + frame.origin.x = 0.0f; + frame.origin.y = 0.0f; + frame.size = [self frame].size; + [ contentView setFrame:frame]; + } + if(chat != nil) { if([chat direction]) { [backgroundImage setImage:[TUNinePatchCache imageOfSize:[backgroundImage bounds].size @@ -69,11 +103,14 @@ static UIFont *CELL_FONT = nil; [backgroundImage setImage:[TUNinePatchCache imageOfSize:[backgroundImage bounds].size forNinePatchNamed:@"chat_bubble_outgoing"]]; } - [messageLabel setText:[chat message]]; } - CGRect frame = [messageLabel frame]; - frame.size.height = [UIChatRoomCell messageHeight:[chat message]]; - [messageLabel setFrame:frame]; + + // Resize message + { + CGRect frame = [messageLabel frame]; + frame.size.height = [UIChatRoomCell messageHeight:[chat message]]; + [messageLabel setFrame:frame]; + } } + (CGFloat)messageHeight:(NSString*)message { @@ -94,21 +131,12 @@ static UIFont *CELL_FONT = nil; return height; } -- (void)enterEditMode { - [deleteButton setHidden:false]; -} - -- (void)exitEditMode { - [deleteButton setHidden:true]; -} #pragma mark - View Functions - (void)layoutSubviews { - // Resize content - CGRect frame = [contentView frame]; - frame.size = [self frame].size; - [contentView setFrame:frame]; + [super layoutSubviews]; + [self resizeContent]; } diff --git a/Classes/LinphoneUI/UIChatRoomCell.xib b/Classes/LinphoneUI/UIChatRoomCell.xib index 57cdb4968..5cc6c4476 100644 --- a/Classes/LinphoneUI/UIChatRoomCell.xib +++ b/Classes/LinphoneUI/UIChatRoomCell.xib @@ -91,7 +91,7 @@ - -2147483351 + 297 {{236, 28}, {44, 44}} diff --git a/Classes/LinphoneUI/UIChatRoomHeader.xib b/Classes/LinphoneUI/UIChatRoomHeader.xib index 937c1726d..c8bdedf3d 100644 --- a/Classes/LinphoneUI/UIChatRoomHeader.xib +++ b/Classes/LinphoneUI/UIChatRoomHeader.xib @@ -39,7 +39,7 @@ 292 - {{-13, -1}, {131, 107}} + {{-13, -5}, {131, 107}} @@ -54,7 +54,7 @@ 274 - {{20, 10}, {65, 65}} + {{20, 6}, {65, 65}} @@ -69,7 +69,7 @@ 292 - {{101, 31}, {199, 43}} + {{101, 27}, {199, 43}} _NS:9 @@ -159,8 +159,8 @@ 4 - + diff --git a/Classes/LinphoneUI/UIConferenceHeader.xib b/Classes/LinphoneUI/UIConferenceHeader.xib index 6839db24a..f88d15e85 100644 --- a/Classes/LinphoneUI/UIConferenceHeader.xib +++ b/Classes/LinphoneUI/UIConferenceHeader.xib @@ -48,7 +48,7 @@ IBCocoaTouchFramework NSImage - champ-titre-conference.png + header_conference.png @@ -57,6 +57,7 @@ {{224, 14}, {25, 25}} + _NS:9 NO IBCocoaTouchFramework @@ -267,7 +268,7 @@ YES 3 - {640, 135} + {640, 135} {43, 50} {43, 46} {43, 46} diff --git a/Classes/LinphoneUI/UIContactCell.h b/Classes/LinphoneUI/UIContactCell.h index d7376d0ad..3032d6f1b 100644 --- a/Classes/LinphoneUI/UIContactCell.h +++ b/Classes/LinphoneUI/UIContactCell.h @@ -23,10 +23,12 @@ @interface UIContactCell : UITableViewCell { UILabel *firstNameLabel; UILabel *lastNameLabel; + UIImageView *avatarImage; } @property (nonatomic, retain) IBOutlet UILabel* firstNameLabel; @property (nonatomic, retain) IBOutlet UILabel* lastNameLabel; +@property (nonatomic, retain) IBOutlet UIImageView *avatarImage; - (void)update:(ABRecordRef) record; diff --git a/Classes/LinphoneUI/UIContactCell.m b/Classes/LinphoneUI/UIContactCell.m index c5ebbf8dd..5f25f29fd 100644 --- a/Classes/LinphoneUI/UIContactCell.m +++ b/Classes/LinphoneUI/UIContactCell.m @@ -23,6 +23,7 @@ @synthesize firstNameLabel; @synthesize lastNameLabel; +@synthesize avatarImage; #pragma mark - Lifecycle Functions @@ -43,6 +44,7 @@ - (void) dealloc { [firstNameLabel release]; [lastNameLabel release]; + [avatarImage release]; [super dealloc]; } @@ -65,12 +67,12 @@ CFStringRef lLocalizedLastName = (lFirstName != nil)?ABAddressBookCopyLocalizedLabel(lLastName):nil; if(lLocalizedFirstName != nil) - [firstNameLabel setText: [(NSString *)lLocalizedFirstName retain]]; + [firstNameLabel setText: (NSString *)lLocalizedFirstName]; else [firstNameLabel setText: @""]; if(lLocalizedLastName != nil) - [lastNameLabel setText: [(NSString *)lLocalizedLastName retain]]; + [lastNameLabel setText: (NSString *)lLocalizedLastName]; else [lastNameLabel setText: @""]; @@ -83,6 +85,17 @@ if(lFirstName != nil) CFRelease(lFirstName); + NSData *imgData = (NSData *)ABPersonCopyImageDataWithFormat(record, kABPersonImageFormatThumbnail); + if(imgData != NULL) { + UIImage *img = [[UIImage alloc] initWithData:imgData]; + [avatarImage setImage:img]; + [img release]; + } else { + [avatarImage setImage:[UIImage imageNamed:@"avatar_unknown_small.png"]]; + } + + + // // Adapt size // diff --git a/Classes/LinphoneUI/UIContactCell.xib b/Classes/LinphoneUI/UIContactCell.xib index 0b24a4a60..bfa83f78e 100644 --- a/Classes/LinphoneUI/UIContactCell.xib +++ b/Classes/LinphoneUI/UIContactCell.xib @@ -36,10 +36,21 @@ 292 + + + 292 + {{6, 6}, {32, 32}} + + + + _NS:9 + NO + IBCocoaTouchFramework + 274 - {{10, 0}, {55, 44}} + {{46, 0}, {55, 44}} @@ -75,7 +86,7 @@ 274 - {{75, 0}, {200, 44}} + {{111, 0}, {200, 44}} _NS:328 @@ -108,6 +119,7 @@ {320, 44} + _NS:9 3 @@ -175,6 +187,14 @@ 22 + + + avatarImage + + + + 24 + @@ -199,8 +219,9 @@ 16 - + + @@ -228,6 +249,12 @@ background + + 23 + + + avatarImage + @@ -239,13 +266,14 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 22 + 24 @@ -253,10 +281,15 @@ UIContactCell UITableViewCell + UIImageView UILabel UILabel + + avatarImage + UIImageView + firstNameLabel UILabel diff --git a/Classes/LinphoneUI/UIContactDetailsHeader.h b/Classes/LinphoneUI/UIContactDetailsHeader.h new file mode 100644 index 000000000..5cc437676 --- /dev/null +++ b/Classes/LinphoneUI/UIContactDetailsHeader.h @@ -0,0 +1,39 @@ +/* UIContactDetailsHeader.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 Library 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. + */ + +#import +#import + +@interface UIContactDetailsHeader : UIViewController { + UILabel *contactLabel; + UIImageView *avatarImage; + + ABRecordRef contact; +} + +@property (assign) ABRecordRef contact; + +@property (nonatomic, retain) IBOutlet UILabel *contactLabel; +@property (nonatomic, retain) IBOutlet UIImageView *avatarImage; + ++ (CGFloat)height; + +- (void)update; + +@end diff --git a/Classes/LinphoneUI/UIContactDetailsHeader.m b/Classes/LinphoneUI/UIContactDetailsHeader.m new file mode 100644 index 000000000..75f61c6d4 --- /dev/null +++ b/Classes/LinphoneUI/UIContactDetailsHeader.m @@ -0,0 +1,81 @@ +/* UIContactDetailsHeader.m + * + * 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 Library 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. + */ + +#import "UIContactDetailsHeader.h" + +@implementation UIContactDetailsHeader + +@synthesize avatarImage; +@synthesize contactLabel; +@synthesize contact; + + +#pragma mark - Lifecycle Functions + +- (id)init { + return [super initWithNibName:@"UIContactDetailsHeader" bundle:[NSBundle mainBundle]]; +} + +- (void)dealloc { + [avatarImage release]; + [contactLabel release]; + [super dealloc]; +} + + +#pragma mark - + +- (void)update { + if(contact) { + // Avatar image + { + NSData *imgData = (NSData *)ABPersonCopyImageDataWithFormat(contact, kABPersonImageFormatThumbnail); + if(imgData != NULL) { + UIImage *img = [[UIImage alloc] initWithData:imgData]; + [avatarImage setImage:img]; + [img release]; + } else { + [avatarImage setImage:[UIImage imageNamed:@"avatar_unknown_small.png"]]; + } + } + + // Contact label + { + CFStringRef lFirstName = ABRecordCopyValue(contact, kABPersonFirstNameProperty); + CFStringRef lLocalizedFirstName = (lFirstName != nil)?ABAddressBookCopyLocalizedLabel(lFirstName):nil; + CFStringRef lLastName = ABRecordCopyValue(contact, kABPersonLastNameProperty); + CFStringRef lLocalizedLastName = (lFirstName != nil)?ABAddressBookCopyLocalizedLabel(lLastName):nil; + [contactLabel setText:[NSString stringWithFormat:@"%@ %@", (NSString*)lLocalizedFirstName, (NSString*)lLocalizedLastName]]; + if(lLocalizedLastName != nil) + CFRelease(lLocalizedLastName); + if(lLastName != nil) + CFRelease(lLastName); + if(lLocalizedFirstName != nil) + CFRelease(lLocalizedFirstName); + if(lFirstName != nil) + CFRelease(lFirstName); + } + } +} + ++ (CGFloat)height { + return 80.0f; +} + +@end diff --git a/Classes/LinphoneUI/UIContactDetailsHeader.xib b/Classes/LinphoneUI/UIContactDetailsHeader.xib new file mode 100644 index 000000000..978e7d5ed --- /dev/null +++ b/Classes/LinphoneUI/UIContactDetailsHeader.xib @@ -0,0 +1,244 @@ + + + + 1296 + 11E53 + 2182 + 1138.47 + 569.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1181 + + + IBUIImageView + IBUIView + IBUILabel + IBProxyObject + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 292 + + + + 292 + {{-13, -5}, {131, 107}} + + + + _NS:9 + NO + IBCocoaTouchFramework + + NSImage + avatar_shadow_small.png + + + + + 274 + {{20, 6}, {65, 65}} + + + + _NS:9 + NO + IBCocoaTouchFramework + + NSImage + avatar_unknown_small.png + + + + + 292 + {{101, 27}, {199, 43}} + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Contact1 + + 3 + MC4zMzMzMzMzMzMzAA + + + 0 + 10 + + 1 + 22 + + + Helvetica + 22 + 16 + + + + {320, 80} + + + + _NS:9 + + 3 + MCAwAA + + IBCocoaTouchFramework + + + + + + + view + + + + 5 + + + + avatarImage + + + + 9 + + + + contactLabel + + + + 11 + + + + + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + + + + 6 + + + avatarImage + + + 7 + + + avatarShadowBackground + + + 8 + + + contactLabel + + + + + UIContactDetailsHeader + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 11 + + + + + UIContactDetailsHeader + UIViewController + + UIImageView + UILabel + + + + avatarImage + UIImageView + + + contactLabel + UILabel + + + + IBProjectSource + ./Classes/UIContactDetailsHeader.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + YES + 3 + + {262, 214} + {131, 131} + + 1181 + + diff --git a/Classes/LinphoneUI/UIHistoryCell.h b/Classes/LinphoneUI/UIHistoryCell.h index 59e4b8ea9..d42efde08 100644 --- a/Classes/LinphoneUI/UIHistoryCell.h +++ b/Classes/LinphoneUI/UIHistoryCell.h @@ -43,7 +43,5 @@ - (IBAction)onDelete:(id) event; - (void)update; -- (void)enterEditMode; -- (void)exitEditMode; @end diff --git a/Classes/LinphoneUI/UIHistoryCell.m b/Classes/LinphoneUI/UIHistoryCell.m index 3ca3d5592..378f145fa 100644 --- a/Classes/LinphoneUI/UIHistoryCell.m +++ b/Classes/LinphoneUI/UIHistoryCell.m @@ -93,25 +93,35 @@ partyToDisplay = callLog->to; } - const char* username = linphone_address_get_username(partyToDisplay)!=0?linphone_address_get_username(partyToDisplay):""; - //const char* displayName = linphone_address_get_display_name(partyToDisplay); - + const char* username = (linphone_address_get_display_name(partyToDisplay) != 0)? linphone_address_get_display_name(partyToDisplay):linphone_address_get_username(partyToDisplay); + [displayNameLabel setText:[NSString stringWithUTF8String: username]]; [imageView setImage: image]; } -- (void)enterEditMode { - [deleteButton setHidden:false]; - [detailsButton setHidden:true]; +- (void)setEditing:(BOOL)editing { + [self setEditing:editing animated:FALSE]; } -- (void)exitEditMode { +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + if(animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + } + if(editing) { + [deleteButton setAlpha:1.0f]; + [detailsButton setAlpha:0.0f]; + } else { #ifdef DETAILS_DISABLED - [detailsButton setHidden:true]; + [detailsButton setAlpha:0.0f]; #else - [detailsButton setHidden:false]; + [detailsButtonsetAlpha:1.0f]; #endif - [deleteButton setHidden:true]; + [deleteButton setAlpha:0.0f]; + } + if(animated) { + [UIView commitAnimations]; + } } @end diff --git a/Classes/LinphoneUI/UIHistoryCell.xib b/Classes/LinphoneUI/UIHistoryCell.xib index bba065224..d921b21d4 100644 --- a/Classes/LinphoneUI/UIHistoryCell.xib +++ b/Classes/LinphoneUI/UIHistoryCell.xib @@ -125,7 +125,7 @@ - -2147483356 + 292 {{276, 0}, {44, 44}} diff --git a/Classes/LinphoneUI/UIMainBar.m b/Classes/LinphoneUI/UIMainBar.m index f49ba5535..8c498efd1 100644 --- a/Classes/LinphoneUI/UIMainBar.m +++ b/Classes/LinphoneUI/UIMainBar.m @@ -86,7 +86,7 @@ } else { historyButton.selected = FALSE; } - if(view == PhoneView_Contacts) { + if(view == PhoneView_Contacts || view == PhoneView_ContactDetails) { contactsButton.selected = TRUE; } else { contactsButton.selected = FALSE; @@ -101,7 +101,7 @@ } else { settingsButton.selected = FALSE; } - if(view == PhoneView_Chat) { + if(view == PhoneView_Chat || view == PhoneView_ChatRoom) { chatButton.selected = TRUE; } else { chatButton.selected = FALSE; diff --git a/Classes/LinphoneUI/UIPauseResumeButton.m b/Classes/LinphoneUI/UIPauseResumeButton.m deleted file mode 100644 index 22f7db8b3..000000000 --- a/Classes/LinphoneUI/UIPauseResumeButton.m +++ /dev/null @@ -1,69 +0,0 @@ -/* UIMuteButton.m - * - * Copyright (C) 2011 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. - */ -#import "UIPauseResumeButton.h" -#include "LinphoneManager.h" - - -@implementation UIPauseResumeButton - - - --(void) onOn { - LinphoneCall* c = linphone_core_get_current_call([LinphoneManager getLc]); - if (c) { - linphone_core_pause_call([LinphoneManager getLc], c); - } -} --(void) onOff { - const MSList* c = linphone_core_get_calls([LinphoneManager getLc]); - if (c) { - linphone_core_resume_call([LinphoneManager getLc], (LinphoneCall*) c->data); - } -} --(bool) isInitialStateOn { - @try { - LinphoneCall* c = linphone_core_get_current_call([LinphoneManager getLc]); - - if (c) { - return linphone_call_get_state(c) == LinphoneCallPaused; - } else { - /* if current call is paused -> c == null */ - return true; - } - } @catch(NSException* e) { - //not ready yet - return false; - } - -} - -/* -// Only override drawRect: if you perform custom drawing. -// An empty implementation adversely affects performance during animation. -- (void)drawRect:(CGRect)rect { - // Drawing code. -} -*/ - -- (void)dealloc { - [super dealloc]; -} - - -@end diff --git a/Classes/LinphoneUI/UITransferButton.m b/Classes/LinphoneUI/UITransferButton.m index 6a105db9b..564e14a4f 100644 --- a/Classes/LinphoneUI/UITransferButton.m +++ b/Classes/LinphoneUI/UITransferButton.m @@ -61,71 +61,11 @@ [super dealloc]; } + #pragma mark - --(void) touchUp:(id) sender { - if (!linphone_core_is_network_reachabled([LinphoneManager getLc])) { - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Network Error",nil) - message:NSLocalizedString(@"There is no network connection available, enable WIFI or WWAN prior to place a call",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - return; - } - - CTCallCenter* ct = [[CTCallCenter alloc] init]; - if ([ct.currentCalls count] > 0) { - ms_error("GSM call in progress, cancelling outgoing SIP call request"); - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot make call",nil) - message:NSLocalizedString(@"Please terminate GSM call",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - [ct release]; - return; - } - [ct release]; - - if (TRUE /*!linphone_core_in_call([LinphoneManager getLc])*/) { - LinphoneProxyConfig* proxyCfg; - //get default proxy - linphone_core_get_default_proxy([LinphoneManager getLc],&proxyCfg); - LinphoneCallParams* lcallParams = linphone_core_create_default_call_parameters([LinphoneManager getLc]); - - if ([addressField.text length] == 0) return; //just return - if ([addressField.text hasPrefix:@"sip:"]) { - linphone_core_transfer_call([LinphoneManager getLc], linphone_core_get_current_call([LinphoneManager getLc]), [addressField.text cStringUsingEncoding:[NSString defaultCStringEncoding]]); - } else if ( proxyCfg==nil){ - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid sip address",nil) - message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to place a call or use a valid sip address (I.E sip:john@example.net)",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - } else { - char normalizedUserName[256]; - NSString* toUserName = [NSString stringWithString:[addressField text]]; - NSString* lDisplayName = [[LinphoneManager instance] getDisplayNameFromAddressBook:toUserName andUpdateCallLog:nil]; - - linphone_proxy_config_normalize_number(proxyCfg,[toUserName cStringUsingEncoding:[NSString defaultCStringEncoding]],normalizedUserName,sizeof(normalizedUserName)); - LinphoneAddress* tmpAddress = linphone_address_new(linphone_core_get_identity([LinphoneManager getLc])); - linphone_address_set_username(tmpAddress,normalizedUserName); - linphone_address_set_display_name(tmpAddress,(lDisplayName)?[lDisplayName cStringUsingEncoding:[NSString defaultCStringEncoding]]:nil); - - - linphone_core_transfer_call([LinphoneManager getLc], linphone_core_get_current_call([LinphoneManager getLc]), normalizedUserName); - - linphone_address_destroy(tmpAddress); - } - linphone_call_params_destroy(lcallParams); - } else if (linphone_core_inc_invite_pending([LinphoneManager getLc])) { - linphone_core_accept_call([LinphoneManager getLc],linphone_core_get_current_call([LinphoneManager getLc])); - } +- (void)touchUp:(id) sender { + [[LinphoneManager instance] call:[addressField text] displayName:nil transfer:TRUE]; } @end diff --git a/Classes/Model/ChatModel.m b/Classes/Model/ChatModel.m index bf81c131b..45e553b30 100644 --- a/Classes/Model/ChatModel.m +++ b/Classes/Model/ChatModel.m @@ -199,7 +199,7 @@ return [[[NSArray alloc] init] autorelease]; } - const char *sql = [[NSString stringWithFormat:@"SELECT id, localContact, remoteContact, direction, message, time FROM chat WHERE remoteContact=\"%@\" ORDER BY time ASC", + const char *sql = [[NSString stringWithFormat:@"SELECT id, localContact, remoteContact, direction, message, time FROM chat WHERE remoteContact=\"%@\" ORDER BY time DESC", contact] UTF8String]; sqlite3_stmt *sqlStatement; if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { diff --git a/Classes/PhoneMainView.h b/Classes/PhoneMainView.h index 3bb0af14d..fab26455c 100644 --- a/Classes/PhoneMainView.h +++ b/Classes/PhoneMainView.h @@ -33,6 +33,7 @@ typedef enum _PhoneView { PhoneView_Chat, PhoneView_ChatRoom, PhoneView_Contacts, + PhoneView_ContactDetails, PhoneView_InCall, PhoneView_IncomingCall, PhoneView_END diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index 7b2cc2ef4..a74aea4df 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -33,6 +33,7 @@ #import "SettingsViewController.h" #import "FirstLoginViewController.h" #import "WizardViewController.h" +#import "ContactDetailsViewController.h" #import "AbstractCall.h" @@ -118,6 +119,7 @@ static PhoneMainView* phoneMainViewInstance=nil; [viewDescriptions setObject:[SettingsViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_Settings]]; [viewDescriptions setObject:[FirstLoginViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_FirstLogin]]; [viewDescriptions setObject:[WizardViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_Wizard]]; + [viewDescriptions setObject:[ContactDetailsViewController compositeViewDescription] forKey:[NSNumber numberWithInt:PhoneView_ContactDetails]]; } - (void)viewWillAppear:(BOOL)animated { diff --git a/Classes/Utils/FastAddressBook.m b/Classes/Utils/FastAddressBook.m index 5cf73de15..cef482195 100644 --- a/Classes/Utils/FastAddressBook.m +++ b/Classes/Utils/FastAddressBook.m @@ -24,13 +24,13 @@ @synthesize addressBook; - -(Contact*) getMatchingRecord:(NSString*) number { +- (Contact*)getMatchingRecord:(NSString*) number { @synchronized (mAddressBookMap){ return (Contact*) [mAddressBookMap objectForKey:number]; } } -+(NSString*) appendCountryCodeIfPossible:(NSString*) number { ++ (NSString*)appendCountryCodeIfPossible:(NSString*) number { if (![number hasPrefix:@"+"] && ![number hasPrefix:@"00"]) { NSString* lCountryCode = [[LinphoneManager instance].settingsStore objectForKey:@"countrycode_preference"]; if (lCountryCode && [lCountryCode length]>0) { @@ -40,7 +40,8 @@ } return number; } -+(NSString*) normalizePhoneNumber:(NSString*) number { + ++ (NSString*)normalizePhoneNumber:(NSString*) number { NSString* lNormalizedNumber = [(NSString*)number stringByReplacingOccurrencesOfString:@" " withString:@""]; lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@"(" withString:@""]; lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@")" withString:@""]; @@ -48,6 +49,7 @@ lNormalizedNumber = [FastAddressBook appendCountryCodeIfPossible:lNormalizedNumber]; return lNormalizedNumber; } + void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) { NSMutableDictionary* lAddressBookMap = (NSMutableDictionary*)context; @synchronized (lAddressBookMap) { @@ -73,31 +75,40 @@ void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void CFRelease(lContacts); } } --(FastAddressBook*) init { + +- (FastAddressBook*)init { if ((self = [super init])) { mAddressBookMap = [[NSMutableDictionary alloc] init]; addressBook = ABAddressBookCreate(); - ABAddressBookRegisterExternalChangeCallback (addressBook,sync_address_book,mAddressBookMap); + ABAddressBookRegisterExternalChangeCallback (addressBook, sync_address_book, mAddressBookMap); sync_address_book(addressBook,nil,mAddressBookMap); } return self; } +- (void)dealloc { + ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, mAddressBookMap); + + [super dealloc]; +} + @end @implementation Contact @synthesize record; @synthesize numberType; --(id) initWithRecord:(ABRecordRef) aRecord ofType:(NSString*) type { +- (id)initWithRecord:(ABRecordRef) aRecord ofType:(NSString*) type { if ((self = [super init])) { record=CFRetain(aRecord); numberType= [type?type:@"unknown" retain]; } return self; } + - (void)dealloc { CFRelease(record); [numberType release]; [super dealloc]; } + @end diff --git a/Resources/cancel_default.png b/Resources/cancel_default.png deleted file mode 100644 index 069a5185d23cfc2f913e510438e6aea455c5c0bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4152 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 diff --git a/Resources/contact_back_default.png b/Resources/contact_back_default.png new file mode 100644 index 0000000000000000000000000000000000000000..3c90a7bb6868b1f7bca3bd8ab9118f83e2d33e52 GIT binary patch literal 4647 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 literal 0 HcmV?d00001 diff --git a/Resources/contact_edit_default.png b/Resources/contact_edit_default.png new file mode 100644 index 0000000000000000000000000000000000000000..428ce5df8eeb1c40d98fd1dbfeab9fa265e49e96 GIT binary patch literal 4596 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 b+8ZZ>XXl#=UO&z|e23B3G0`s4atQl3jMW$I literal 0 HcmV?d00001 diff --git a/Resources/contact_edit_over.png b/Resources/contact_edit_over.png new file mode 100644 index 0000000000000000000000000000000000000000..62c0a4c34508a136cd65a41651ef8f20ddcd9f70 GIT binary patch literal 4284 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 xC%L9;4qx#DNN9jd+v1!r^ouIvg5% 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 literal 0 HcmV?d00001 diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index f30b4deb9..bd29d5d5e 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -153,6 +153,18 @@ 7066FC0C13E830E400EFC6DC /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0B13E830E400EFC6DC /* libvpx.a */; }; 70E542F313E147E3002BA2C0 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F213E147E3002BA2C0 /* OpenGLES.framework */; }; 70E542F513E147EB002BA2C0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F413E147EB002BA2C0 /* QuartzCore.framework */; }; + D3128FE115AABC7E00A2147A /* ContactDetailsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3128FDF15AABC7E00A2147A /* ContactDetailsViewController.m */; }; + D3128FE215AABC7E00A2147A /* ContactDetailsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3128FDF15AABC7E00A2147A /* ContactDetailsViewController.m */; }; + D3128FE315AABC7E00A2147A /* ContactDetailsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE015AABC7E00A2147A /* ContactDetailsViewController.xib */; }; + D3128FE415AABC7E00A2147A /* ContactDetailsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE015AABC7E00A2147A /* ContactDetailsViewController.xib */; }; + D3128FEF15AABE4E00A2147A /* contact_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE715AABE4E00A2147A /* contact_back_default.png */; }; + D3128FF015AABE4E00A2147A /* contact_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE715AABE4E00A2147A /* contact_back_default.png */; }; + D3128FF115AABE4E00A2147A /* contact_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE815AABE4E00A2147A /* contact_back_over.png */; }; + D3128FF215AABE4E00A2147A /* contact_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE815AABE4E00A2147A /* contact_back_over.png */; }; + D3128FF315AABE4E00A2147A /* contact_edit_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE915AABE4E00A2147A /* contact_edit_default.png */; }; + D3128FF415AABE4E00A2147A /* contact_edit_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE915AABE4E00A2147A /* contact_edit_default.png */; }; + D3128FF515AABE4E00A2147A /* contact_edit_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FEA15AABE4E00A2147A /* contact_edit_over.png */; }; + D3128FF615AABE4E00A2147A /* contact_edit_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FEA15AABE4E00A2147A /* contact_edit_over.png */; }; D3196D2D15A3199D007FEEBA /* list_hightlight.png in Resources */ = {isa = PBXBuildFile; fileRef = D3196D2C15A3199D007FEEBA /* list_hightlight.png */; }; D3196D2E15A3199D007FEEBA /* list_hightlight.png in Resources */ = {isa = PBXBuildFile; fileRef = D3196D2C15A3199D007FEEBA /* list_hightlight.png */; }; D3196D3415A321E3007FEEBA /* options_add_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3196D3015A321E2007FEEBA /* options_add_default.png */; }; @@ -362,6 +374,16 @@ D37B96B815A1A6F20005CCD2 /* call_state_delete_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D37B96B515A1A6F20005CCD2 /* call_state_delete_default.png */; }; D37B96B915A1A6F20005CCD2 /* call_state_delete_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D37B96B615A1A6F20005CCD2 /* call_state_delete_over.png */; }; D37B96BA15A1A6F20005CCD2 /* call_state_delete_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D37B96B615A1A6F20005CCD2 /* call_state_delete_over.png */; }; + D37C638E15AAD251009D0BAC /* contact_number_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D37C638C15AAD251009D0BAC /* contact_number_over.png */; }; + D37C638F15AAD251009D0BAC /* contact_number_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D37C638C15AAD251009D0BAC /* contact_number_over.png */; }; + D37C639015AAD251009D0BAC /* contact_number.png in Resources */ = {isa = PBXBuildFile; fileRef = D37C638D15AAD251009D0BAC /* contact_number.png */; }; + D37C639115AAD251009D0BAC /* contact_number.png in Resources */ = {isa = PBXBuildFile; fileRef = D37C638D15AAD251009D0BAC /* contact_number.png */; }; + D37C639515AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D37C639315AADDAE009D0BAC /* UIContactDetailsHeader.m */; }; + D37C639615AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D37C639315AADDAE009D0BAC /* UIContactDetailsHeader.m */; }; + D37C639715AADDAF009D0BAC /* UIContactDetailsHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37C639415AADDAF009D0BAC /* UIContactDetailsHeader.xib */; }; + D37C639815AADDAF009D0BAC /* UIContactDetailsHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37C639415AADDAF009D0BAC /* UIContactDetailsHeader.xib */; }; + D37C639B15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D37C639A15AADEF5009D0BAC /* ContactDetailsTableViewController.m */; }; + D37C639C15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D37C639A15AADEF5009D0BAC /* ContactDetailsTableViewController.m */; }; D37DC6C11594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */; }; D37DC6C21594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */; }; D37DC6ED1594AE6F00B2A5EB /* IASKAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6C61594AE6F00B2A5EB /* IASKAppSettingsViewController.m */; }; @@ -667,10 +689,6 @@ D3F83F7D1582253100336684 /* decline_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F761582253100336684 /* decline_default.png */; }; D3F83F7E1582253100336684 /* decline_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F771582253100336684 /* decline_over.png */; }; D3F83F7F1582253100336684 /* decline_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F771582253100336684 /* decline_over.png */; }; - D3F83F841582278D00336684 /* cancel_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F801582278D00336684 /* cancel_default.png */; }; - D3F83F851582278D00336684 /* cancel_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F801582278D00336684 /* cancel_default.png */; }; - D3F83F861582278D00336684 /* cancel_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F811582278D00336684 /* cancel_over.png */; }; - D3F83F871582278D00336684 /* cancel_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F811582278D00336684 /* cancel_over.png */; }; D3F83F8E15822ABE00336684 /* PhoneMainView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F83F8D15822ABD00336684 /* PhoneMainView.m */; }; D3F83F8F15822ABE00336684 /* PhoneMainView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F83F8D15822ABD00336684 /* PhoneMainView.m */; }; D3F83F9215824D3600336684 /* LinphoneApp.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F9115824D3500336684 /* LinphoneApp.xib */; }; @@ -1001,6 +1019,13 @@ 70E542F213E147E3002BA2C0 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; 70E542F413E147EB002BA2C0 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 8D1107310486CEB800E47090 /* linphone-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "linphone-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + D3128FDE15AABC7E00A2147A /* ContactDetailsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsViewController.h; sourceTree = ""; }; + D3128FDF15AABC7E00A2147A /* ContactDetailsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailsViewController.m; sourceTree = ""; }; + D3128FE015AABC7E00A2147A /* ContactDetailsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContactDetailsViewController.xib; sourceTree = ""; }; + D3128FE715AABE4E00A2147A /* contact_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_back_default.png; path = Resources/contact_back_default.png; sourceTree = ""; }; + D3128FE815AABE4E00A2147A /* contact_back_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_back_over.png; path = Resources/contact_back_over.png; sourceTree = ""; }; + D3128FE915AABE4E00A2147A /* contact_edit_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_edit_default.png; path = Resources/contact_edit_default.png; sourceTree = ""; }; + D3128FEA15AABE4E00A2147A /* contact_edit_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_edit_over.png; path = Resources/contact_edit_over.png; sourceTree = ""; }; D3196D2C15A3199D007FEEBA /* list_hightlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = list_hightlight.png; path = Resources/list_hightlight.png; sourceTree = ""; }; D3196D3015A321E2007FEEBA /* options_add_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_add_default.png; path = Resources/options_add_default.png; sourceTree = ""; }; D3196D3115A321E2007FEEBA /* options_add_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_add_over.png; path = Resources/options_add_over.png; sourceTree = ""; }; @@ -1130,6 +1155,13 @@ D377BBF915A19DA6002B696B /* video_on_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_on_disabled.png; path = Resources/video_on_disabled.png; sourceTree = ""; }; D37B96B515A1A6F20005CCD2 /* call_state_delete_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_delete_default.png; path = Resources/call_state_delete_default.png; sourceTree = ""; }; D37B96B615A1A6F20005CCD2 /* call_state_delete_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_delete_over.png; path = Resources/call_state_delete_over.png; sourceTree = ""; }; + D37C638C15AAD251009D0BAC /* contact_number_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_number_over.png; path = Resources/contact_number_over.png; sourceTree = ""; }; + D37C638D15AAD251009D0BAC /* contact_number.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_number.png; path = Resources/contact_number.png; sourceTree = ""; }; + D37C639215AADDAE009D0BAC /* UIContactDetailsHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIContactDetailsHeader.h; sourceTree = ""; }; + D37C639315AADDAE009D0BAC /* UIContactDetailsHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIContactDetailsHeader.m; sourceTree = ""; }; + D37C639415AADDAF009D0BAC /* UIContactDetailsHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UIContactDetailsHeader.xib; sourceTree = ""; }; + D37C639915AADEF4009D0BAC /* ContactDetailsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsTableViewController.h; sourceTree = ""; }; + D37C639A15AADEF5009D0BAC /* ContactDetailsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailsTableViewController.m; sourceTree = ""; }; D37DC6BF1594AE1800B2A5EB /* LinphoneCoreSettingsStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinphoneCoreSettingsStore.h; sourceTree = ""; }; D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneCoreSettingsStore.m; sourceTree = ""; }; D37DC6C51594AE6F00B2A5EB /* IASKAppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKAppSettingsViewController.h; sourceTree = ""; }; @@ -1322,8 +1354,6 @@ D3F83F751582253100336684 /* accept_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = accept_over.png; path = Resources/accept_over.png; sourceTree = ""; }; D3F83F761582253100336684 /* decline_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = decline_default.png; path = Resources/decline_default.png; sourceTree = ""; }; D3F83F771582253100336684 /* decline_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = decline_over.png; path = Resources/decline_over.png; sourceTree = ""; }; - D3F83F801582278D00336684 /* cancel_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cancel_default.png; path = Resources/cancel_default.png; sourceTree = ""; }; - D3F83F811582278D00336684 /* cancel_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cancel_over.png; path = Resources/cancel_over.png; sourceTree = ""; }; D3F83F8C158229C500336684 /* PhoneMainView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhoneMainView.h; sourceTree = ""; }; D3F83F8D15822ABD00336684 /* PhoneMainView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhoneMainView.m; sourceTree = ""; }; D3F83F9115824D3500336684 /* LinphoneApp.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LinphoneApp.xib; sourceTree = ""; }; @@ -1449,6 +1479,11 @@ 22E0A820111C44E100B04932 /* ConsoleViewController.h */, 22E0A81F111C44E100B04932 /* ConsoleViewController.m */, 22E0A81E111C44E100B04932 /* ConsoleViewController.xib */, + D37C639915AADEF4009D0BAC /* ContactDetailsTableViewController.h */, + D37C639A15AADEF5009D0BAC /* ContactDetailsTableViewController.m */, + D3128FDE15AABC7E00A2147A /* ContactDetailsViewController.h */, + D3128FDF15AABC7E00A2147A /* ContactDetailsViewController.m */, + D3128FE015AABC7E00A2147A /* ContactDetailsViewController.xib */, D3549814158761CF000081D8 /* ContactsTableViewController.h */, D3549815158761D0000081D8 /* ContactsTableViewController.m */, D35497FB15875372000081D8 /* ContactsViewController.h */, @@ -1744,6 +1779,9 @@ D3A55FBA15877E5E003FD403 /* UIContactCell.h */, D3A55FBB15877E5E003FD403 /* UIContactCell.m */, D3A55FBE15877E69003FD403 /* UIContactCell.xib */, + D37C639215AADDAE009D0BAC /* UIContactDetailsHeader.h */, + D37C639315AADDAE009D0BAC /* UIContactDetailsHeader.m */, + D37C639415AADDAF009D0BAC /* UIContactDetailsHeader.xib */, 2248E90C12F7E4CF00220D9C /* UIDigitButton.h */, 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */, 22BB1A67132FF16A005CD7AA /* UIEraseButton.h */, @@ -1938,7 +1976,6 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( - D3D14E7B15A711700074A527 /* avatar_shadow_small.png */, D3F83F741582253100336684 /* accept_default.png */, D3F83F751582253100336684 /* accept_over.png */, D3D6A39B159B0EEF005F692C /* add_call_default.png */, @@ -1948,6 +1985,7 @@ D3ED3E6815861A53006C0DE4 /* add_contact_disabled.png */, D3ED3E6915861A53006C0DE4 /* add_contact_over.png */, D3F34F2F1599B008005BE94F /* avatar_shadow.png */, + D3D14E7B15A711700074A527 /* avatar_shadow_small.png */, D31B4B261598A390002E6C72 /* avatar_unknown.png */, D31B4B271598A390002E6C72 /* avatar_unknown_small.png */, D3211BBB159CBFD60098460B /* back_default.png */, @@ -1976,8 +2014,6 @@ D31C9C8D158A1C1000756B45 /* call_status_incoming.png */, D31C9C8E158A1C1000756B45 /* call_status_missed.png */, D31C9C8F158A1C1000756B45 /* call_status_outgoing.png */, - D3F83F801582278D00336684 /* cancel_default.png */, - D3F83F811582278D00336684 /* cancel_over.png */, D36C43CC158F2F370048BA40 /* cell_call.png */, D3211BB8159C8A820098460B /* cell_call_first.png */, D38D14AD15A30B3D008497E8 /* cell_call_first_hightlight.png */, @@ -2004,6 +2040,12 @@ D3B9A3DE15A58C450096EA4E /* chat_send_over.png */, D31AAF61159B5B6E002C6B02 /* conference_default.png */, D31AAF62159B5B6E002C6B02 /* conference_over.png */, + D3128FE715AABE4E00A2147A /* contact_back_default.png */, + D3128FE815AABE4E00A2147A /* contact_back_over.png */, + D3128FE915AABE4E00A2147A /* contact_edit_default.png */, + D3128FEA15AABE4E00A2147A /* contact_edit_over.png */, + D37C638D15AAD251009D0BAC /* contact_number.png */, + D37C638C15AAD251009D0BAC /* contact_number_over.png */, D354980E15875608000081D8 /* contacts_add_default.png */, D354980F15875608000081D8 /* contacts_add_over.png */, D354980315875534000081D8 /* contacts_all_default.png */, @@ -2442,8 +2484,6 @@ D3F83F7A1582253100336684 /* accept_over.png in Resources */, D3F83F7C1582253100336684 /* decline_default.png in Resources */, D3F83F7E1582253100336684 /* decline_over.png in Resources */, - D3F83F841582278D00336684 /* cancel_default.png in Resources */, - D3F83F861582278D00336684 /* cancel_over.png in Resources */, D3F83F9215824D3600336684 /* LinphoneApp.xib in Resources */, D3ED3E411585FB4A006C0DE4 /* numpad_background.png in Resources */, D3ED3E451585FB8C006C0DE4 /* dialer_address_background.png in Resources */, @@ -2595,6 +2635,14 @@ D389363B15A6D53200A3A3AA /* chat_bubble_outgoing.9.png in Resources */, D3D14E7915A70EE30074A527 /* UIChatRoomHeader.xib in Resources */, D3D14E7C15A711700074A527 /* avatar_shadow_small.png in Resources */, + D3128FE315AABC7E00A2147A /* ContactDetailsViewController.xib in Resources */, + D3128FEF15AABE4E00A2147A /* contact_back_default.png in Resources */, + D3128FF115AABE4E00A2147A /* contact_back_over.png in Resources */, + D3128FF315AABE4E00A2147A /* contact_edit_default.png in Resources */, + D3128FF515AABE4E00A2147A /* contact_edit_over.png in Resources */, + D37C638E15AAD251009D0BAC /* contact_number_over.png in Resources */, + D37C639015AAD251009D0BAC /* contact_number.png in Resources */, + D37C639715AADDAF009D0BAC /* UIContactDetailsHeader.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2663,8 +2711,6 @@ D3F83F7B1582253100336684 /* accept_over.png in Resources */, D3F83F7D1582253100336684 /* decline_default.png in Resources */, D3F83F7F1582253100336684 /* decline_over.png in Resources */, - D3F83F851582278D00336684 /* cancel_default.png in Resources */, - D3F83F871582278D00336684 /* cancel_over.png in Resources */, D3F83F9315824D3600336684 /* LinphoneApp.xib in Resources */, D3ED3E421585FB4A006C0DE4 /* numpad_background.png in Resources */, D3ED3E461585FB8C006C0DE4 /* dialer_address_background.png in Resources */, @@ -2815,6 +2861,14 @@ D389363C15A6D53200A3A3AA /* chat_bubble_outgoing.9.png in Resources */, D3D14E7A15A70EE30074A527 /* UIChatRoomHeader.xib in Resources */, D3D14E7D15A711700074A527 /* avatar_shadow_small.png in Resources */, + D3128FE415AABC7E00A2147A /* ContactDetailsViewController.xib in Resources */, + D3128FF015AABE4E00A2147A /* contact_back_default.png in Resources */, + D3128FF215AABE4E00A2147A /* contact_back_over.png in Resources */, + D3128FF415AABE4E00A2147A /* contact_edit_default.png in Resources */, + D3128FF615AABE4E00A2147A /* contact_edit_over.png in Resources */, + D37C638F15AAD251009D0BAC /* contact_number_over.png in Resources */, + D37C639115AAD251009D0BAC /* contact_number.png in Resources */, + D37C639815AADDAF009D0BAC /* UIContactDetailsHeader.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2897,6 +2951,9 @@ D389362615A6D19800A3A3AA /* CPAnimationSequence.m in Sources */, D389362815A6D19800A3A3AA /* CPAnimationStep.m in Sources */, D3D14E7715A70EE30074A527 /* UIChatRoomHeader.m in Sources */, + D3128FE115AABC7E00A2147A /* ContactDetailsViewController.m in Sources */, + D37C639515AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */, + D37C639B15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2976,6 +3033,9 @@ D389362715A6D19800A3A3AA /* CPAnimationSequence.m in Sources */, D389362915A6D19800A3A3AA /* CPAnimationStep.m in Sources */, D3D14E7815A70EE30074A527 /* UIChatRoomHeader.m in Sources */, + D3128FE215AABC7E00A2147A /* ContactDetailsViewController.m in Sources */, + D37C639615AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */, + D37C639C15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };