diff --git a/Classes/ChatRoomTableViewController.h b/Classes/ChatRoomTableViewController.h new file mode 100644 index 000000000..16aba4943 --- /dev/null +++ b/Classes/ChatRoomTableViewController.h @@ -0,0 +1,29 @@ +/* ChatRoomTableViewController.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 + +@interface ChatRoomTableViewController : UITableViewController { + NSArray *data; +} + +@property (nonatomic, retain) NSArray *data; + +@end diff --git a/Classes/ChatRoomTableViewController.m b/Classes/ChatRoomTableViewController.m new file mode 100644 index 000000000..1600d97c5 --- /dev/null +++ b/Classes/ChatRoomTableViewController.m @@ -0,0 +1,60 @@ +/* ChatRoomTableViewController.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 "ChatRoomTableViewController.h" +#import "UIChatCell.h" + +@implementation ChatRoomTableViewController + +@synthesize data; + + +#pragma mark - + +- (void)setData:(NSArray *)adata { + if(self->data != nil) + [self->data release]; + self->data = [adata retain]; + [[self tableView] reloadData]; +} + + +#pragma mark - UITableViewDataSource Functions + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [data count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UIChatCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UIChatCell"]; + if (cell == nil) { + cell = [[UIChatCell alloc] init]; + } + + [cell setChat:[data objectAtIndex:[indexPath row]]]; + [cell update]; + + return cell; +} + +@end diff --git a/Classes/ChatRoomViewController.h b/Classes/ChatRoomViewController.h new file mode 100644 index 000000000..7890a147c --- /dev/null +++ b/Classes/ChatRoomViewController.h @@ -0,0 +1,44 @@ +/* ChatRoomViewController.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 "UICompositeViewController.h" +#import "ChatRoomTableViewController.h" +#import "ChatModel.h" + +@interface ChatRoomViewController : UIViewController { + ChatRoomTableViewController *tableController; + UITextField *messageField; + UIButton *sendButton; +} + +- (void) setRemoteContact:(NSString*)remoteContact; + +@property (nonatomic, retain) IBOutlet ChatRoomTableViewController* tableController; + +@property (nonatomic, retain) IBOutlet UITextField* messageField; +@property (nonatomic, retain) IBOutlet UIButton* sendButton; + +- (IBAction)onBackClick:(id)event; +- (IBAction)onEditClick:(id)event; +- (IBAction)onMessageChange:(id)sender; +- (IBAction)onSendClick:(id)event; + +@end diff --git a/Classes/ChatRoomViewController.m b/Classes/ChatRoomViewController.m new file mode 100644 index 000000000..5f517b280 --- /dev/null +++ b/Classes/ChatRoomViewController.m @@ -0,0 +1,160 @@ +/* ChatRoomViewController.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 "ChatRoomViewController.h" +#import "PhoneMainView.h" + +@implementation ChatRoomViewController + + +@synthesize tableController; +@synthesize sendButton; +@synthesize messageField; + + +#pragma mark - Lifecycle Functions + +- (id)init { + return [super initWithNibName:@"ChatRoomViewController" bundle:[NSBundle mainBundle]]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; +} + +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription*) compositeViewDescription { + UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"ChatRoomViewController"; + description->tabBar = nil; + description->tabBarEnabled = false; + description->stateBar = nil; + description->stateBarEnabled = false; + description->fullscreen = false; + return description; +} + + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillHide:) + name:UIKeyboardWillHideNotification + object:nil]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [[tableController tableView] reloadData]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIKeyboardWillHideNotification + object:nil]; +} + + +#pragma mark - + +- (void)setRemoteContact:(NSString*)remoteContact { + [tableController setData:[ChatModel listMessages:remoteContact]]; +} + + +#pragma mark - Keyboard Event Functions + +- (void)keyboardWillHide:(NSNotification *)notif { + //CGRect beginFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; + UIViewAnimationCurve curve = [[[notif userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]; + NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + [UIView beginAnimations:@"resize" context:nil]; + [UIView setAnimationDuration:duration]; + [UIView setAnimationCurve:curve]; + [UIView setAnimationBeginsFromCurrentState:TRUE]; + CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGRect frame = [[self view] frame]; + CGPoint pos = {0, 0}; + CGPoint gPos = [[self view] convertPoint:pos toView:nil]; + frame.size.height = endFrame.origin.y - gPos.y; + [[self view] setFrame:frame]; + [UIView commitAnimations]; +} + +- (void)keyboardWillShow:(NSNotification *)notif { + //CGRect beginFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; + UIViewAnimationCurve curve = [[[notif userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]; + NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + [UIView beginAnimations:@"resize" context:nil]; + [UIView setAnimationDuration:duration]; + [UIView setAnimationCurve:curve]; + [UIView setAnimationBeginsFromCurrentState:TRUE]; + CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGRect frame = [[self view] frame]; + CGPoint pos = {0, 0}; + CGPoint gPos = [[self view] convertPoint:pos toView:nil]; + frame.size.height = endFrame.origin.y - gPos.y; + [[self view] setFrame:frame]; + [UIView commitAnimations]; +} + +#pragma mark - UITextFieldDelegate Functions + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + [textField resignFirstResponder]; + return YES; +} + + +#pragma mark - Action Functions + +- (IBAction)onBackClick:(id)event { + [[PhoneMainView instance] popView]; +} + +- (IBAction)onEditClick:(id)event { + +} + +- (IBAction)onSendClick:(id)event { + [messageField endEditing:TRUE]; +} + +- (IBAction)onMessageChange:(id)sender { + if([[messageField text] length] > 0) { + [sendButton setEnabled:TRUE]; + } else { + [sendButton setEnabled:FALSE]; + } +} + +@end diff --git a/Classes/ChatRoomViewController.xib b/Classes/ChatRoomViewController.xib new file mode 100644 index 000000000..a363aec5e --- /dev/null +++ b/Classes/ChatRoomViewController.xib @@ -0,0 +1,580 @@ + + + + 1296 + 11E53 + 2182 + 1138.47 + 569.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1181 + + + IBUIView + IBUIImageView + IBProxyObject + IBUITextField + IBUITableViewController + IBUITableView + IBUIButton + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 292 + + + + 290 + + + + 292 + {160, 58} + + + + _NS:9 + NO + + All + + IBCocoaTouchFramework + 0 + 0 + NO + + 3 + MC41AA + + + NSImage + chat_back_over.png + + + NSImage + chat_back_default.png + + + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + + + + 292 + {{160, 0}, {160, 58}} + + + + _NS:9 + NO + + Missed + + IBCocoaTouchFramework + 0 + 0 + NO + + + NSImage + chat_edit_over.png + + + NSImage + chat_edit_default.png + + + + + + {320, 58} + + + + _NS:9 + + 3 + MQA + + 2 + + + IBCocoaTouchFramework + + + + 274 + {{0, 58}, {320, 344}} + + + + _NS:9 + + 1 + MC45NDExNzY0NzA2IDAuOTY0NzA1ODgyNCAwLjk2NDcwNTg4MjQAA + + YES + IBCocoaTouchFramework + YES + 1 + 0 + YES + 44 + 22 + 22 + + + + 266 + + + + 292 + {{250, 0}, {70, 59}} + + + + _NS:9 + NO + + Missed + + IBCocoaTouchFramework + NO + 0 + 0 + NO + NO + + + NSImage + chat_send_over.png + + + NSImage + chat_send_disabled.png + + + NSImage + chat_send_default.png + + + + + + + 292 + {250, 59} + + + + _NS:9 + NO + IBCocoaTouchFramework + + NSImage + chat_field.png + + + + + 292 + {{10, 10}, {230, 39}} + + + + _NS:9 + NO + YES + IBCocoaTouchFramework + 0 + + Type your message here + + 3 + MAA + + + YES + 17 + + IBCocoaTouchFramework + + + 1 + 18 + + + Helvetica + 18 + 16 + + + + {{0, 401}, {320, 59}} + + + + _NS:9 + + 3 + MQA + + + IBCocoaTouchFramework + + + {320, 460} + + + + _NS:9 + + 3 + MQA + + + IBCocoaTouchFramework + + + NO + + + 1 + 1 + + IBCocoaTouchFramework + NO + + + + + + + view + + + + 11 + + + + messageField + + + + 26 + + + + sendButton + + + + 27 + + + + tableController + + + + 32 + + + + dataSource + + + + 30 + + + + delegate + + + + 31 + + + + onBackClick: + + + 7 + + 12 + + + + onEditClick: + + + 7 + + 13 + + + + onSendClick: + + + 7 + + 25 + + + + delegate + + + + 20 + + + + onMessageChange: + + + 18 + + 28 + + + + view + + + + 33 + + + + + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 6 + + + + + + + + + + 7 + + + + + + + header + + + 8 + + + + tableView + + + 9 + + + backButton + + + 10 + + + editButton + + + 14 + + + + + + + + footer + + + 15 + + + sendButton + + + 19 + + + messageField + + + 21 + + + fieldBackground + + + 29 + + + tableController + + + + + ChatRoomViewController + 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 + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + ChatRoomTableViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + + 33 + + + + + ChatRoomTableViewController + UITableViewController + + IBProjectSource + ./Classes/ChatRoomTableViewController.h + + + + ChatRoomViewController + UIViewController + + id + id + id + id + + + + onBackClick: + id + + + onEditClick: + id + + + onMessageChange: + id + + + onSendClick: + id + + + + UITextField + UIButton + ChatRoomTableViewController + + + + messageField + UITextField + + + sendButton + UIButton + + + tableController + ChatRoomTableViewController + + + + IBProjectSource + ./Classes/ChatRoomViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + YES + 3 + + {320, 117} + {320, 117} + {320, 117} + {320, 117} + {500, 117} + {140, 117} + {140, 117} + {140, 117} + + 1181 + + diff --git a/Classes/ChatTableViewController.h b/Classes/ChatTableViewController.h index 2b9367245..32cd1f67e 100644 --- a/Classes/ChatTableViewController.h +++ b/Classes/ChatTableViewController.h @@ -20,7 +20,9 @@ #import @interface ChatTableViewController : UITableViewController { - + NSArray *data; } +@property (nonatomic, retain) NSArray *data; + @end diff --git a/Classes/ChatTableViewController.m b/Classes/ChatTableViewController.m index 969125b08..b72bd9a6f 100644 --- a/Classes/ChatTableViewController.m +++ b/Classes/ChatTableViewController.m @@ -20,8 +20,24 @@ #import "ChatTableViewController.h" #import "UIChatCell.h" +#import "linphonecore.h" +#import "PhoneMainView.h" + @implementation ChatTableViewController +@synthesize data; + + +#pragma mark - + +- (void)setData:(NSArray *)adata { + if(self->data != nil) + [self->data release]; + self->data = [adata retain]; + [[self tableView] reloadData]; +} + +#pragma mark - UITableViewDataSource Functions - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { @@ -30,7 +46,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return 1; + return [data count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath @@ -40,9 +56,25 @@ cell = [[UIChatCell alloc] init]; } + [cell setChat:[data objectAtIndex:[indexPath row]]]; [cell update]; return cell; } + +#pragma mark - UITableViewDelegate Functions + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:NO]; + ChatModel *chat = [data objectAtIndex:[indexPath row]]; + + // Go to dialer view + NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: + [[[NSArray alloc] initWithObjects: [chat remoteContact], nil] autorelease] + , @"setRemoteContact:", + nil] autorelease]; + [[PhoneMainView instance] changeView:PhoneView_ChatRoom dict:dict push:TRUE]; +} + @end diff --git a/Classes/ChatViewController.h b/Classes/ChatViewController.h index a6df7bda6..ac61c32c0 100644 --- a/Classes/ChatViewController.h +++ b/Classes/ChatViewController.h @@ -20,14 +20,15 @@ #import #import "ChatTableViewController.h" +#import "UICompositeViewController.h" -@interface ChatViewController : UIViewController { +@interface ChatViewController : UIViewController { ChatTableViewController *tableController; } @property (nonatomic, retain) IBOutlet ChatTableViewController* tableController; -- (IBAction)onAdd:(id) event; -- (IBAction)onEdit:(id) event; +- (IBAction)onAddClick:(id) event; +- (IBAction)onEditClick:(id) event; @end diff --git a/Classes/ChatViewController.m b/Classes/ChatViewController.m index 5f52c3bd7..2e769e36c 100644 --- a/Classes/ChatViewController.m +++ b/Classes/ChatViewController.m @@ -18,21 +18,58 @@ */ #import "ChatViewController.h" +#import "PhoneMainView.h" +#import "ChatModel.h" @implementation ChatViewController @synthesize tableController; + +#pragma mark - Lifecycle Functions + - (id)init { return [super initWithNibName:@"ChatViewController" bundle:[NSBundle mainBundle]]; } -- (IBAction)onAdd: (id) event { - + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [tableController setData:[ChatModel listConversations]]; } -- (IBAction)onEdit: (id) event { +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription*) compositeViewDescription { + UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"ChatViewController"; + description->tabBar = @"UIMainBar"; + description->tabBarEnabled = true; + description->stateBar = nil; + description->stateBarEnabled = false; + description->fullscreen = false; + return description; +} + + +#pragma mark - Action Functions + +- (IBAction)onAddClick:(id)event { + [[PhoneMainView instance] changeView:PhoneView_ChatRoom push:TRUE]; +} + +- (IBAction)onEditClick:(id)event { + ChatModel* line= [[ChatModel alloc] init]; + line.localContact = @""; + line.remoteContact = @"truc"; + line.message = @"blabla"; + line.direction = [NSNumber numberWithInt:1]; + line.time = [NSDate date]; + [line create]; + [tableController setData:[ChatModel listConversations]]; } @end diff --git a/Classes/ChatViewController.xib b/Classes/ChatViewController.xib index 3145cd267..bd88f20eb 100644 --- a/Classes/ChatViewController.xib +++ b/Classes/ChatViewController.xib @@ -69,10 +69,6 @@ NSImage chat_add_default.png - - NSImage - all-call-selectionne.png - 2 15 @@ -108,10 +104,6 @@ NSImage chat_edit_default.png - - NSImage - missed-selectionne.png - @@ -139,8 +131,8 @@ _NS:9 - 3 - MQA + 1 + MC45NDExNzY0NzA2IDAuOTY0NzA1ODgyNCAwLjk2NDcwNTg4MjQAA YES IBCocoaTouchFramework @@ -224,21 +216,21 @@ - onEdit: + onEditClick: 7 - 17 + 21 - onAdd: + onAddClick: 7 - 19 + 20 @@ -311,20 +303,20 @@ UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - + ChatTableViewController com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - + - 19 + 21 @@ -340,16 +332,16 @@ ChatViewController UIViewController - id - id + id + id - - onAdd: + + onAddClick: id - - onEdit: + + onEditClick: id @@ -380,12 +372,10 @@ YES 3 - {213, 117} {320, 117} {320, 117} {320, 117} {320, 117} - {213, 117} 1181 diff --git a/Classes/ContactsTableViewController.h b/Classes/ContactsTableViewController.h index 5ef07e6ea..696b0ef7e 100644 --- a/Classes/ContactsTableViewController.h +++ b/Classes/ContactsTableViewController.h @@ -22,7 +22,7 @@ #import "OrderedDictionary.h" -@interface ContactsTableViewController : UITableViewController { +@interface ContactsTableViewController : UITableViewController { OrderedDictionary* addressBookMap; ABAddressBookRef addressBook; diff --git a/Classes/ContactsTableViewController.m b/Classes/ContactsTableViewController.m index 55c1b33d2..f67ce8f71 100644 --- a/Classes/ContactsTableViewController.m +++ b/Classes/ContactsTableViewController.m @@ -20,6 +20,7 @@ #import "ContactsTableViewController.h" #import "UIContactCell.h" #import "LinphoneManager.h" +#import "PhoneMainView.h" @implementation ContactsTableViewController @@ -127,7 +128,7 @@ void sync_toc_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, [[[NSArray alloc] initWithObjects: number, nil] autorelease] , @"setAddress:", nil] autorelease]; - [[LinphoneManager instance] changeView:PhoneView_Dialer dict:dict]; + [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; CFRelease(lNumber); break; diff --git a/Classes/ContactsViewController.h b/Classes/ContactsViewController.h index 50326d42f..f713dd8b7 100644 --- a/Classes/ContactsViewController.h +++ b/Classes/ContactsViewController.h @@ -19,9 +19,11 @@ #import +#import "UICompositeViewController.h" + #import "ContactsTableViewController.h" -@interface ContactsViewController : UIViewController { +@interface ContactsViewController : UIViewController { ContactsTableViewController *tableController; UITableView *tableView; diff --git a/Classes/ContactsViewController.m b/Classes/ContactsViewController.m index c5fa9e9b7..436f5739b 100644 --- a/Classes/ContactsViewController.m +++ b/Classes/ContactsViewController.m @@ -51,6 +51,21 @@ typedef enum _HistoryView { [super dealloc]; } + +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription*) compositeViewDescription { + UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"ContactsViewController"; + description->tabBar = @"UIMainBar"; + description->tabBarEnabled = true; + description->stateBar = nil; + description->stateBarEnabled = false; + description->fullscreen = false; + return description; +} + + #pragma mark - ViewController Functions - (void)viewDidAppear:(BOOL)animated { diff --git a/Classes/Data/ChatData.h b/Classes/Data/ChatData.h new file mode 100644 index 000000000..dddef8c50 --- /dev/null +++ b/Classes/Data/ChatData.h @@ -0,0 +1,13 @@ +// +// ChatData.h +// linphone +// +// Created by Diorcet Yann on 05/07/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import + +@interface ChatData : NSObject + +@end diff --git a/Classes/Data/ChatData.m b/Classes/Data/ChatData.m new file mode 100644 index 000000000..f8aa72dc1 --- /dev/null +++ b/Classes/Data/ChatData.m @@ -0,0 +1,13 @@ +// +// ChatData.m +// linphone +// +// Created by Diorcet Yann on 05/07/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "ChatData.h" + +@implementation ChatData + +@end diff --git a/Classes/DialerViewController.h b/Classes/DialerViewController.h index f08360063..8a90e2b63 100644 --- a/Classes/DialerViewController.h +++ b/Classes/DialerViewController.h @@ -19,12 +19,14 @@ #import +#import "UICompositeViewController.h" + #import "UIEraseButton.h" #import "UICallButton.h" #import "UITransferButton.h" #import "UIDigitButton.h" -@interface DialerViewController : UIViewController { +@interface DialerViewController : UIViewController { @private //Buttons UITextField* addressField; diff --git a/Classes/DialerViewController.m b/Classes/DialerViewController.m index a8774c35f..90bc9123c 100644 --- a/Classes/DialerViewController.m +++ b/Classes/DialerViewController.m @@ -83,17 +83,52 @@ [zeroButton release]; [sharpButton release]; + + // Remove all observers [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription *)compositeViewDescription { + UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"DialerViewController"; + description->tabBar = @"UIMainBar"; + description->tabBarEnabled = true; + description->stateBar = @"UIStateBar"; + description->stateBarEnabled = true; + description->fullscreen = false; + return description; +} + + #pragma mark - ViewController Functions - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; - [self update]; + + // Set observer + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdateEvent:) + name:@"LinphoneCallUpdate" + object:nil]; + + // Update on show + LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); + LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0; + [self callUpdate:call state:state]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + // Remove observer + [[NSNotificationCenter defaultCenter] removeObserver:self + name:@"LinphoneCallUpdate" + object:nil]; } - (void)viewDidLoad { @@ -111,26 +146,20 @@ [nineButton setDigit:'9']; [starButton setDigit:'*']; [sharpButton setDigit:'#']; - - // Set observer - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callUpdate:) name:@"LinphoneCallUpdate" object:nil]; } -- (void)viewDidUnload { - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - - #pragma mark - Event Functions -- (void)callUpdate:(NSNotification*)notif { - [self update]; +- (void)callUpdateEvent:(NSNotification*)notif { + LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; + LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue]; + [self callUpdate:call state:state]; } #pragma mark - -- (void)update { +- (void)callUpdate:(LinphoneCall*)call state:(LinphoneCallState)state { if([LinphoneManager isLcReady]) { LinphoneCore *lc = [LinphoneManager getLc]; if(linphone_core_get_calls_nb(lc) > 0) { @@ -160,7 +189,9 @@ - (void)setTransferMode:(NSNumber*) n { transferMode = [n boolValue]; - [self update]; + LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); + LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0; + [self callUpdate:call state:state]; } @@ -181,7 +212,7 @@ } - (IBAction)onBackClick: (id) event { - [[LinphoneManager instance] changeView:PhoneView_InCall]; + [[PhoneMainView instance] changeView:PhoneView_InCall]; } - (IBAction)onAddressChange: (id)sender { diff --git a/Classes/DialerViewController.xib b/Classes/DialerViewController.xib index dfe28c0d4..952fbc8bd 100644 --- a/Classes/DialerViewController.xib +++ b/Classes/DialerViewController.xib @@ -521,7 +521,7 @@ NSImage - cancel_white_bg_disabled.png + back_disabled.png @@ -1286,7 +1286,7 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - + UICallButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1677,6 +1677,7 @@ add_contact_disabled.png add_contact_over.png back_default.png + back_disabled.png back_over.png backspace_default.png backspace_disabled.png @@ -1684,7 +1685,6 @@ call_default.png call_disabled.png call_over.png - cancel_white_bg_disabled.png dialer_address_background.png numpad_background.png numpad_eight_default.png @@ -1725,10 +1725,10 @@ {213, 138} {213, 138} {213, 138} - {214, 138} - {214, 138} - {214, 138} {213, 138} + {214, 138} + {214, 138} + {214, 138} {640, 135} {640, 523} {220, 113} diff --git a/Classes/FirstLoginViewController.h b/Classes/FirstLoginViewController.h index 12e3f0ace..5f9961cbf 100644 --- a/Classes/FirstLoginViewController.h +++ b/Classes/FirstLoginViewController.h @@ -19,7 +19,9 @@ #import -@interface FirstLoginViewController : UIViewController{ +#import "UICompositeViewController.h" + +@interface FirstLoginViewController : UIViewController { UIButton* loginButton; UIButton* siteButton; UITextField* usernameField; diff --git a/Classes/FirstLoginViewController.m b/Classes/FirstLoginViewController.m index d3f202da5..cf47635c9 100644 --- a/Classes/FirstLoginViewController.m +++ b/Classes/FirstLoginViewController.m @@ -20,6 +20,7 @@ #import "FirstLoginViewController.h" #import "LinphoneManager.h" +#import "PhoneMainView.h" @implementation FirstLoginViewController @@ -36,21 +37,63 @@ } - (void)dealloc { - [super dealloc]; [loginButton dealloc]; [siteButton dealloc]; [usernameField dealloc]; [passwordField dealloc]; [waitView dealloc]; + + // Remove all observer [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; } + +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription *)compositeViewDescription { + UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"FirstLoginViewController"; + description->tabBar = nil; + description->tabBarEnabled = false; + description->stateBar = nil; + description->stateBarEnabled = false; + description->fullscreen = false; + return description; +} + + #pragma mark - ViewController Functions -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; [usernameField setText:[[LinphoneManager instance].settingsStore objectForKey:@"username_preference"]]; [passwordField setText:[[LinphoneManager instance].settingsStore objectForKey:@"password_preference"]]; + + // Set observer + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(registrationUpdateEvent:) + name:@"LinphoneRegistrationUpdate" + object:nil]; + + // Update on show + const MSList* list = linphone_core_get_proxy_config_list([LinphoneManager getLc]); + if(list != NULL) { + LinphoneProxyConfig *config = (LinphoneProxyConfig*) list->data; + if(config) { + [self registrationUpdate:linphone_proxy_config_get_state(config)]; + } + } +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + // Remove observer + [[NSNotificationCenter defaultCenter] removeObserver:self + name:@"LinphoneRegistrationUpdate" + object:nil]; } - (void)viewDidLoad { @@ -59,26 +102,24 @@ siteUrl=@"http://www.linphone.org"; } [siteButton setTitle:siteUrl forState:UIControlStateNormal]; - - // Set observer - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registrationUpdate:) name:@"LinphoneRegistrationUpdate" object:nil]; } -- (void)viewDidUnload { - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - - #pragma mark - Event Functions -- (void)registrationUpdate: (NSNotification*) notif { - LinphoneRegistrationState state = [[notif.userInfo objectForKey: @"state"] intValue]; +- (void)registrationUpdateEvent:(NSNotification*)notif { + [self registrationUpdate:[[notif.userInfo objectForKey: @"state"] intValue]]; +} + + +#pragma mark - + +- (void)registrationUpdate:(LinphoneRegistrationState)state { switch (state) { case LinphoneRegistrationOk: { [[LinphoneManager instance].settingsStore setBool:false forKey:@"enable_first_login_view_preference"]; [self.waitView setHidden:true]; - [[LinphoneManager instance] changeView:PhoneView_Dialer]; + [[PhoneMainView instance] changeView:PhoneView_Dialer]; break; } case LinphoneRegistrationNone: diff --git a/Classes/HistoryTableViewController.h b/Classes/HistoryTableViewController.h index b668e5fc4..09f55b9e7 100644 --- a/Classes/HistoryTableViewController.h +++ b/Classes/HistoryTableViewController.h @@ -19,7 +19,7 @@ #import -@interface HistoryTableViewController : UITableViewController { +@interface HistoryTableViewController : UITableViewController { @private BOOL editMode; } diff --git a/Classes/HistoryTableViewController.m b/Classes/HistoryTableViewController.m index 83635f53a..33747e013 100644 --- a/Classes/HistoryTableViewController.m +++ b/Classes/HistoryTableViewController.m @@ -20,6 +20,7 @@ #import "HistoryTableViewController.h" #import "UIHistoryCell.h" #import "LinphoneManager.h" +#import "PhoneMainView.h" @implementation HistoryTableViewController @@ -58,11 +59,15 @@ else [cell exitEditMode]; - [cell update:callLogs]; + [cell setCallLog:callLogs]; + [cell update]; return cell; } + +#pragma mark - UITableViewDelegate Functions + - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:NO]; @@ -96,7 +101,7 @@ [[[NSArray alloc] initWithObjects: phoneNumber, nil] autorelease] , @"setAddress:", nil] autorelease]; - [[LinphoneManager instance] changeView:PhoneView_Dialer dict:dict]; + [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; [phoneNumber release]; [dispName release]; diff --git a/Classes/HistoryViewController.h b/Classes/HistoryViewController.h index 10b329ab0..93025f1b7 100644 --- a/Classes/HistoryViewController.h +++ b/Classes/HistoryViewController.h @@ -19,10 +19,11 @@ #import +#import "UICompositeViewController.h" #import "HistoryTableViewController.h" #import "UIToggleButton.h" -@interface HistoryViewController : UIViewController { +@interface HistoryViewController : UIViewController { @private HistoryTableViewController *tableController; UITableView *tableView; diff --git a/Classes/HistoryViewController.m b/Classes/HistoryViewController.m index 766282145..8b2aa9e46 100644 --- a/Classes/HistoryViewController.m +++ b/Classes/HistoryViewController.m @@ -53,6 +53,19 @@ typedef enum _HistoryView { } +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription*) compositeViewDescription { + UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"HistoryViewController"; + description->tabBar = @"UIMainBar"; + description->tabBarEnabled = true; + description->stateBar = nil; + description->stateBarEnabled = false; + description->fullscreen = false; + return description; +} + #pragma mark - ViewController Functions - (void)viewDidAppear:(BOOL)animated { diff --git a/Classes/InCallTableViewController.h b/Classes/InCallTableViewController.h index 1ccd38a08..99abc4d60 100644 --- a/Classes/InCallTableViewController.h +++ b/Classes/InCallTableViewController.h @@ -23,7 +23,7 @@ #include "linphonecore.h" -@interface InCallTableViewController : UITableViewController { +@interface InCallTableViewController : UITableViewController { @private NSMutableDictionary* callCellData; NSTimer *updateTime; diff --git a/Classes/InCallViewController.h b/Classes/InCallViewController.h index 651baac8e..b11f30ae3 100644 --- a/Classes/InCallViewController.h +++ b/Classes/InCallViewController.h @@ -23,11 +23,12 @@ #import "UICamSwitch.h" #import "CallDelegate.h" +#import "UICompositeViewController.h" #import "InCallTableViewController.h" @class VideoViewController; -@interface InCallViewController : UIViewController { +@interface InCallViewController : UIViewController { InCallTableViewController* callTableController; UITableView* callTableView; diff --git a/Classes/InCallViewController.m b/Classes/InCallViewController.m index 01b0699fc..e3690a931 100644 --- a/Classes/InCallViewController.m +++ b/Classes/InCallViewController.m @@ -27,6 +27,7 @@ #import "IncallViewController.h" #import "UICallCell.h" #import "LinphoneManager.h" +#import "PhoneMainView.h" #include "linphonecore.h" #include "private.h" @@ -71,10 +72,27 @@ const NSInteger SECURE_BUTTON_TAG=5; [videoZoomHandler release]; + // Remove all observer + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; } +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription*) compositeViewDescription { + UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"InCallViewController"; + description->tabBar = @"UICallBar"; + description->tabBarEnabled = true; + description->stateBar = @"UIStateBar"; + description->stateBarEnabled = true; + description->fullscreen = false; + return description; +} + + #pragma mark - ViewController Functions - (void)viewDidAppear:(BOOL)animated { @@ -101,6 +119,12 @@ const NSInteger SECURE_BUTTON_TAG=5; if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) { [callTableController viewWillDisappear:NO]; } + + + // Remove observer + [[NSNotificationCenter defaultCenter] removeObserver:self + name:@"LinphoneCallUpdate" + object:nil]; } - (void)viewWillAppear:(BOOL)animated { @@ -108,6 +132,17 @@ const NSInteger SECURE_BUTTON_TAG=5; if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) { [callTableController viewWillAppear:NO]; } + + // Set observer + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdateEvent:) + name:@"LinphoneCallUpdate" + object:nil]; + + // Update on show + LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); + LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0; + [self callUpdate:call state:state]; } - (void)viewDidDisappear:(BOOL)animated { @@ -122,10 +157,6 @@ const NSInteger SECURE_BUTTON_TAG=5; } } -- (void)viewDidUnload { - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - - (void)viewDidLoad { [super viewDidLoad]; @@ -133,10 +164,6 @@ const NSInteger SECURE_BUTTON_TAG=5; linphone_core_set_native_video_window_id([LinphoneManager getLc],(unsigned long)videoView); linphone_core_set_native_preview_window_id([LinphoneManager getLc],(unsigned long)videoPreview); - // Set observer - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callUpdate:) name:@"LinphoneCallUpdate" object:nil]; - - UITapGestureRecognizer* singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)]; [singleFingerTap setNumberOfTapsRequired:1]; [singleFingerTap setCancelsTouchesInView: FALSE]; @@ -153,6 +180,80 @@ const NSInteger SECURE_BUTTON_TAG=5; #pragma mark - + +- (void)callUpdate:(LinphoneCall *)call state:(LinphoneCallState) state { + // Update table + [callTableView reloadData]; + + // Fake call update + if(call == NULL) { + return; + } + + // Handle data associated with the call + if(state == LinphoneCallReleased) { + [callTableController removeCallData: call]; + } else { + [callTableController addCallData: call]; + } + + switch (state) { + case LinphoneCallIncomingReceived: + case LinphoneCallOutgoingInit: + { + if(linphone_core_get_calls_nb([LinphoneManager getLc]) > 1) { + [callTableController minimizeAll]; + } + } + case LinphoneCallConnected: + case LinphoneCallStreamsRunning: + case LinphoneCallUpdated: + { + //check video + if (linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { + [self displayVideoCall]; + } else { + [self displayTableCall]; + } + break; + } + case LinphoneCallUpdatedByRemote: + { + const LinphoneCallParams* current = linphone_call_get_current_params(call); + const LinphoneCallParams* remote = linphone_call_get_remote_params(call); + + /* remote wants to add video */ + if (!linphone_call_params_video_enabled(current) && + linphone_call_params_video_enabled(remote) && + !linphone_core_get_video_policy([LinphoneManager getLc])->automatically_accept) { + linphone_core_defer_call_update([LinphoneManager getLc], call); + [self displayAskToEnableVideoCall:call]; + } else if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) { + [self displayTableCall]; + } + break; + } + case LinphoneCallPausing: + case LinphoneCallPaused: + case LinphoneCallPausedByRemote: + { + [self displayTableCall]; + break; + } + case LinphoneCallEnd: + case LinphoneCallError: + { + if(linphone_core_get_calls_nb([LinphoneManager getLc]) <= 1) { + [callTableController maximizeAll]; + } + break; + } + default: + break; + } + +} + - (void)showControls:(id)sender { if (hideControlsTimer) { [hideControlsTimer invalidate]; @@ -162,7 +263,7 @@ const NSInteger SECURE_BUTTON_TAG=5; // show controls [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:0.3]; - [[LinphoneManager instance] showTabBar: true]; + [[PhoneMainView instance] showTabBar: true]; if ([LinphoneManager instance].frontCamId !=nil ) { // only show camera switch button if we have more than 1 camera [videoCameraSwitch setAlpha:1.0]; @@ -183,8 +284,8 @@ const NSInteger SECURE_BUTTON_TAG=5; [videoCameraSwitch setAlpha:0.0]; [UIView commitAnimations]; - if([[LinphoneManager instance] currentView] == PhoneView_InCall && videoShown) - [[LinphoneManager instance] showTabBar: false]; + if([[PhoneMainView instance] currentView] == PhoneView_InCall && videoShown) + [[PhoneMainView instance] showTabBar: false]; if (hideControlsTimer) { [hideControlsTimer invalidate]; @@ -228,8 +329,8 @@ const NSInteger SECURE_BUTTON_TAG=5; videoView.alpha = 1.0; videoView.hidden = FALSE; - [[LinphoneManager instance] fullScreen: true]; - [[LinphoneManager instance] showTabBar: false]; + [[PhoneMainView instance] fullScreen: true]; + [[PhoneMainView instance] showTabBar: false]; #ifdef TEST_VIDEO_VIEW_CHANGE [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(_debugChangeVideoView) userInfo:nil repeats:YES]; @@ -256,7 +357,7 @@ const NSInteger SECURE_BUTTON_TAG=5; } [videoGroup setAlpha:0.0]; - [[LinphoneManager instance] showTabBar: true]; + [[PhoneMainView instance] showTabBar: true]; [callTableView setAlpha:1.0]; [videoCameraSwitch setAlpha:0.0]; @@ -269,7 +370,7 @@ const NSInteger SECURE_BUTTON_TAG=5; hideControlsTimer = nil; } - [[LinphoneManager instance] fullScreen:false]; + [[PhoneMainView instance] fullScreen:false]; } - (void)transferPressed { @@ -314,7 +415,7 @@ const NSInteger SECURE_BUTTON_TAG=5; //TODO /*[UICallButton enableTransforMode:YES];*/ - [[LinphoneManager instance] changeView:PhoneView_Dialer]; + [[PhoneMainView instance] changeView:PhoneView_Dialer]; } else { // add 'Other' option [visibleActionSheet addButtonWithTitle:NSLocalizedString(@"Other...",nil)]; @@ -332,11 +433,11 @@ const NSInteger SECURE_BUTTON_TAG=5; } } -- (void)displayVideoCall:(LinphoneCall*) call { +- (void)displayVideoCall { [self enableVideoDisplay: TRUE]; } -- (void)displayTableCall:(LinphoneCall*) call { +- (void)displayTableCall { [self disableVideoDisplay: TRUE]; } @@ -352,84 +453,16 @@ static void hideSpinner(LinphoneCall* call, void* user_data) { [thiz hideSpinnerIndicator:call]; } + #pragma mark - Event Functions -- (void)callUpdate: (NSNotification*) notif { +- (void)callUpdateEvent: (NSNotification*) notif { LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue]; - - // Update table - [callTableView reloadData]; - - // Fake call update - if(call == NULL) { - return; - } - - // Handle data associated with the call - if(state == LinphoneCallReleased) { - [callTableController removeCallData: call]; - } else { - [callTableController addCallData: call]; - } - - switch (state) { - case LinphoneCallIncomingReceived: - case LinphoneCallOutgoingInit: - { - if(linphone_core_get_calls_nb([LinphoneManager getLc]) > 1) { - [callTableController minimizeAll]; - } - } - case LinphoneCallConnected: - case LinphoneCallStreamsRunning: - case LinphoneCallUpdated: - { - //check video - if (linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { - [self displayVideoCall:call]; - } else { - [self displayTableCall:call]; - } - break; - } - case LinphoneCallUpdatedByRemote: - { - const LinphoneCallParams* current = linphone_call_get_current_params(call); - const LinphoneCallParams* remote = linphone_call_get_remote_params(call); - - /* remote wants to add video */ - if (!linphone_call_params_video_enabled(current) && - linphone_call_params_video_enabled(remote) && - !linphone_core_get_video_policy([LinphoneManager getLc])->automatically_accept) { - linphone_core_defer_call_update([LinphoneManager getLc], call); - [self displayAskToEnableVideoCall:call]; - } else if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) { - [self displayTableCall:call]; - } - break; - } - case LinphoneCallPausing: - case LinphoneCallPaused: - case LinphoneCallPausedByRemote: - { - [self displayTableCall: call]; - break; - } - case LinphoneCallEnd: - case LinphoneCallError: - { - if(linphone_core_get_calls_nb([LinphoneManager getLc]) <= 1) { - [callTableController maximizeAll]; - } - break; - } - default: - break; - } - + [self callUpdate:call state:state]; } + #pragma mark - ActionSheet Functions - (void)dismissActionSheet: (id)o { @@ -523,7 +556,7 @@ static void hideSpinner(LinphoneCall* call, void* user_data) { // with the correct indice //TODO //[UICallButton enableTransforMode:YES]; - [[LinphoneManager instance] changeView:PhoneView_Dialer]; + [[PhoneMainView instance] changeView:PhoneView_Dialer]; break; } default: diff --git a/Classes/IncomingCallViewController.h b/Classes/IncomingCallViewController.h index ba2a9563a..dbdbc41e0 100644 --- a/Classes/IncomingCallViewController.h +++ b/Classes/IncomingCallViewController.h @@ -38,12 +38,9 @@ typedef enum _IncomingCallStates { @property (nonatomic, retain) IBOutlet UILabel* addressLabel; @property (nonatomic, retain) IBOutlet UIImageView* avatarImage; +@property (nonatomic, assign) LinphoneCall* call; - (IBAction)onAcceptClick:(id) event; - (IBAction)onDeclineClick:(id) event; -- (void)update:(LinphoneCall*)call; - -- (LinphoneCall*) getCall; - @end diff --git a/Classes/IncomingCallViewController.m b/Classes/IncomingCallViewController.m index 47965e2c3..744422fea 100644 --- a/Classes/IncomingCallViewController.m +++ b/Classes/IncomingCallViewController.m @@ -24,19 +24,13 @@ @synthesize addressLabel; @synthesize avatarImage; +@synthesize call; #pragma mark - Lifecycle Functions - (id)init { - self = [super initWithNibName:@"IncomingCallViewController" bundle:[NSBundle mainBundle]]; - if(self) { - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(callUpdate:) - name:@"LinphoneCallUpdate" - object:nil]; - } - return self; + return [super initWithNibName:@"IncomingCallViewController" bundle:[NSBundle mainBundle]]; } - (void)dealloc { @@ -46,20 +40,50 @@ } +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdateEvent:) + name:@"LinphoneCallUpdate" + object:nil]; + + [self callUpdate:call state:linphone_call_get_state(call)]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [[NSNotificationCenter defaultCenter] removeObserver:self + name:@"LinphoneCallUpdate" + object:nil]; +} + + + #pragma mark - Event Functions -- (void)callUpdate:(NSNotification*)notif { +- (void)callUpdateEvent:(NSNotification*)notif { LinphoneCall *acall = [[notif.userInfo objectForKey: @"call"] pointerValue]; LinphoneCallState astate = [[notif.userInfo objectForKey: @"state"] intValue]; + [self callUpdate:acall state:astate]; +} + + +#pragma mark - + +- (void)callUpdate:(LinphoneCall *)acall state:(LinphoneCallState)astate { if(call == acall && (astate == LinphoneCallEnd || astate == LinphoneCallError)) { [self dismiss: IncomingCall_Aborted]; } } -#pragma mark - +#pragma mark - Property Functions -- (void)update:(LinphoneCall*)acall { +- (void)setCall:(LinphoneCall*)acall { [self view]; //Force view load call = acall; diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index d3428ce89..6f9234573 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -143,14 +143,14 @@ int __aeabi_idiv(int a, int b) { - (void)setupUI { if ([[LinphoneManager instance].settingsStore boolForKey:@"enable_first_login_view_preference"] == true) { // Change to fist login view - [[LinphoneManager instance] changeView: PhoneView_FirstLogin]; + [[PhoneMainView instance] changeView: PhoneView_FirstLogin]; } else { // Change to default view const MSList *list = linphone_core_get_proxy_config_list([LinphoneManager getLc]); if(list != NULL) { - [[LinphoneManager instance] changeView: PhoneView_Dialer]; + [[PhoneMainView instance] changeView: PhoneView_Dialer]; } else { - [[LinphoneManager instance] changeView: PhoneView_Wizard]; + [[PhoneMainView instance] changeView: PhoneView_Wizard]; } } diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index 0079dd8e3..7328d6df2 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -20,6 +20,7 @@ #import #import #import +#import #import "LogView.h" #import "IASKSettingsReader.h" @@ -28,19 +29,6 @@ #include "linphonecore.h" -typedef enum _PhoneView { - PhoneView_Wizard, - PhoneView_FirstLogin, - PhoneView_Dialer, - PhoneView_History, - PhoneView_Settings, - PhoneView_Chat, - PhoneView_Contacts, - PhoneView_InCall, - PhoneView_IncomingCall, - PhoneView_END -} PhoneView; - typedef enum _Connectivity { wifi, wwan @@ -79,9 +67,8 @@ typedef struct _LinphoneCallAppData { const char* frontCamId; const char* backCamId; - PhoneView currentView; - id settingsStore; + sqlite3 *database; @public CallContext currentCallContextBeforeGoingBackground; @@ -108,12 +95,6 @@ typedef struct _LinphoneCallAppData { - (void)setupNetworkReachabilityCallback; - (void)refreshRegisters; -- (void)changeView:(PhoneView) view; -- (void)changeView:(PhoneView) view dict:(NSDictionary *)dict; -- (void)showTabBar:(BOOL) show; -- (void)fullScreen:(BOOL) enabled; -- (PhoneView) currentView; - - (void)enableSpeaker:(BOOL)enable; - (BOOL)isSpeakerEnabled; @@ -123,6 +104,7 @@ typedef struct _LinphoneCallAppData { @property (nonatomic) int defaultExpires; @property (readonly) const char* frontCamId; @property (readonly) const char* backCamId; +@property (readonly) sqlite3* database; @end diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index cbff80a55..fd56aacc4 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -58,13 +58,12 @@ extern void libmsbcg729_init(); @implementation LinphoneManager -PhoneView currentView = -1; - @synthesize connectivity; @synthesize frontCamId; @synthesize backCamId; @synthesize defaultExpires; @synthesize settingsStore; +@synthesize database; struct codec_name_pref_table{ const char *name; @@ -110,46 +109,59 @@ struct codec_name_pref_table codec_pref_table[]={ - (id)init { assert (!theLinphoneManager); - if ((self= [super init])) { + if ((self = [super init])) { mFastAddressBook = [[FastAddressBook alloc] init]; + database = NULL; theLinphoneManager = self; - self.defaultExpires=600; + self.defaultExpires = 600; + [self openDatabase]; } return self; } +- (void)dealloc { + [mFastAddressBook release]; + [self closeDatabase]; + + [super dealloc]; +} + +- (void)openDatabase { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsPath = [paths objectAtIndex:0]; + NSString *databaseDocumentPath = [documentsPath stringByAppendingPathComponent:@"database.txt"]; + + // Copy default database + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error = nil; + //[fileManager removeItemAtPath:databaseDocumentPath error:&error]; //TODO REMOVE + if ([fileManager fileExistsAtPath:databaseDocumentPath] == NO) { + NSLog(@"Create sqlite 3 database"); + NSString *resourceDocumentPath = [[NSBundle mainBundle] pathForResource:@"database" ofType:@"sqlite"]; + [fileManager copyItemAtPath:resourceDocumentPath toPath:databaseDocumentPath error:&error]; + if(error != nil) { + NSLog(@"Can't copy database: %@", [error localizedDescription]); + return; + } + } + + if(sqlite3_open([databaseDocumentPath UTF8String], &database) != SQLITE_OK) { + NSLog(@"Can't open \"%@\" sqlite3 database.", databaseDocumentPath); + } +} + +- (void)closeDatabase { + if(database != NULL) { + if(sqlite3_close(database) != SQLITE_OK) { + NSLog(@"Can't close sqlite3 database."); + } + } +} + + (LinphoneManager*)instance { return theLinphoneManager; } -- (void) showTabBar:(BOOL) show { - NSMutableDictionary* mdict = [NSMutableDictionary dictionaryWithObject: [NSNumber numberWithBool:show] forKey:@"tabBar"]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"LinphoneMainViewChange" object:self userInfo:mdict]; -} - -- (void)fullScreen:(BOOL) enabled { - NSMutableDictionary* mdict = [NSMutableDictionary dictionaryWithObject: [NSNumber numberWithBool:enabled] forKey:@"fullscreen"]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"LinphoneMainViewChange" object:self userInfo:mdict]; -} - -- (void)changeView:(PhoneView) view { - [self changeView:view dict:nil]; -} - -- (void)changeView:(PhoneView) view dict:(NSDictionary *)dict { - currentView = view; - - NSMutableDictionary* mdict = [NSMutableDictionary dictionaryWithObject: [NSNumber numberWithInt:currentView] forKey:@"view"]; - if(dict != nil) - [mdict setObject:dict forKey:@"args"]; - - [[NSNotificationCenter defaultCenter] postNotificationName:@"LinphoneMainViewChange" object:self userInfo:mdict]; -} - -- (PhoneView)currentView { - return currentView; -} - -(NSString*) getDisplayNameFromAddressBook:(NSString*) number andUpdateCallLog:(LinphoneCallLog*)log { //1 normalize NSString* lNormalizedNumber = [FastAddressBook normalizePhoneNumber:number]; diff --git a/Classes/LinphoneUI/UICallBar.m b/Classes/LinphoneUI/UICallBar.m index 4e0b4d8b7..dad26c74b 100644 --- a/Classes/LinphoneUI/UICallBar.m +++ b/Classes/LinphoneUI/UICallBar.m @@ -19,6 +19,7 @@ #import "UICallBar.h" #import "LinphoneManager.h" +#import "PhoneMainView.h" #import "CPAnimationSequence.h" #import "CPAnimationStep.h" @@ -125,8 +126,6 @@ [sharpButton setDigit:'#']; [sharpButton setDtmf:true]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callUpdate:) name:@"LinphoneCallUpdate" object:nil]; - // Set selected+disabled background: IB lack ! [videoButton setImage:[UIImage imageNamed:@"video_on_disabled.png"] forState:(UIControlStateDisabled | UIControlStateSelected)]; @@ -153,17 +152,40 @@ forState:(UIControlStateHighlighted | UIControlStateSelected)]; } -- (void)viewDidUnload { - [[NSNotificationCenter defaultCenter] removeObserver:self]; +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdateEvent:) + name:@"LinphoneCallUpdate" + object:nil]; + + // Update on show + LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); + LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0; + [self callUpdate:call state:state]; } +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [[NSNotificationCenter defaultCenter] removeObserver:self + name:@"LinphoneCallUpdate" + object:nil]; +} #pragma mark - Event Functions -- (void)callUpdate: (NSNotification*) notif { - //LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; +- (void)callUpdateEvent:(NSNotification*)notif { + LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue]; - + [self callUpdate:call state:state]; +} + + +#pragma mark - + +- (void)callUpdate:(LinphoneCall*)call state:(LinphoneCallState)state { LinphoneCore* lc = [LinphoneManager getLc]; [speakerButton update]; @@ -335,7 +357,7 @@ [[[NSArray alloc] initWithObjects: [NSNumber numberWithInt: TRUE], nil] autorelease] , @"setTransferMode:", nil] autorelease]; - [[LinphoneManager instance] changeView:PhoneView_Dialer dict:dict]; + [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; } - (IBAction)onOptionsAddClick:(id)sender { @@ -347,7 +369,7 @@ [[[NSArray alloc] initWithObjects: [NSNumber numberWithInt: FALSE], nil] autorelease] , @"setTransferMode:", nil] autorelease]; - [[LinphoneManager instance] changeView:PhoneView_Dialer dict:dict]; + [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; } - (IBAction)onOptionsClick:(id)sender { diff --git a/Classes/LinphoneUI/UIChatCell.h b/Classes/LinphoneUI/UIChatCell.h index 6d10e6374..2cfdede30 100644 --- a/Classes/LinphoneUI/UIChatCell.h +++ b/Classes/LinphoneUI/UIChatCell.h @@ -19,17 +19,24 @@ #import +#import "ChatModel.h" + @interface UIChatCell : UITableViewCell { UIImageView *avatarView; UILabel *displayNameLabel; UILabel *chatContentLabel; + + ChatModel *chat; } +- (void)update; + +@property (weak) ChatModel *chat; + @property (nonatomic, retain) IBOutlet UIImageView *avatarView; @property (nonatomic, retain) IBOutlet UILabel* displayNameLabel; @property (nonatomic, retain) IBOutlet UILabel* chatContentLabel; -- (IBAction)onDetails: (id) event; +- (IBAction)onDetails:(id)event; -- (void)update; @end diff --git a/Classes/LinphoneUI/UIChatCell.m b/Classes/LinphoneUI/UIChatCell.m index 6d0a7737d..5f3973769 100644 --- a/Classes/LinphoneUI/UIChatCell.m +++ b/Classes/LinphoneUI/UIChatCell.m @@ -25,6 +25,7 @@ @synthesize displayNameLabel; @synthesize chatContentLabel; +@synthesize chat; #pragma mark - Lifecycle Functions @@ -50,31 +51,33 @@ #pragma mark - -- (void)update{ +- (void)update { + [avatarView setImage:[UIImage imageNamed:@"avatar_unknown_small.png"]]; - [avatarView setImage:[UIImage imageNamed:@"avatar-small.png"]]; + [displayNameLabel setText:[chat remoteContact]]; + [chatContentLabel setText:[chat message]]; // // Adapt size // - CGRect firstNameFrame = [displayNameLabel frame]; - CGRect lastNameFrame = [chatContentLabel frame]; + CGRect displayNameFrame = [displayNameLabel frame]; + CGRect chatContentFrame = [chatContentLabel frame]; - lastNameFrame.origin.x -= firstNameFrame.size.width; + chatContentFrame.origin.x -= displayNameFrame.size.width; // Compute firstName size CGSize contraints; contraints.height = [displayNameLabel frame].size.height; contraints.width = ([chatContentLabel frame].size.width + [chatContentLabel frame].origin.x) - [displayNameLabel frame].origin.x; CGSize firstNameSize = [[displayNameLabel text] sizeWithFont:[displayNameLabel font] constrainedToSize: contraints]; - firstNameFrame.size.width = firstNameSize.width; + displayNameFrame.size.width = firstNameSize.width; // Compute lastName size & position - lastNameFrame.origin.x += firstNameFrame.size.width; - lastNameFrame.size.width = (contraints.width + [displayNameLabel frame].origin.x) - lastNameFrame.origin.x; + chatContentFrame.origin.x += displayNameFrame.size.width; + chatContentFrame.size.width = (contraints.width + [displayNameLabel frame].origin.x) - chatContentFrame.origin.x; - [displayNameLabel setFrame: firstNameFrame]; - [chatContentLabel setFrame: lastNameFrame]; + [displayNameLabel setFrame: displayNameFrame]; + [chatContentLabel setFrame: chatContentFrame]; } diff --git a/Classes/LinphoneUI/UIChatCell.xib b/Classes/LinphoneUI/UIChatCell.xib index dcdc7cd9d..dbf9b0730 100644 --- a/Classes/LinphoneUI/UIChatCell.xib +++ b/Classes/LinphoneUI/UIChatCell.xib @@ -47,6 +47,10 @@ _NS:9 NO IBCocoaTouchFramework + + NSImage + avatar_unknown_small.png + @@ -123,6 +127,7 @@ {{276, 0}, {44, 44}} + _NS:9 NO IBCocoaTouchFramework @@ -133,25 +138,17 @@ 11 11 11 - - 3 - MQA - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - 3 MC41AA NSImage - bouton-detail-contact-over.png + list_details_over.png NSImage - bouton-detail-contact-actif.png + list_details_default.png 2 @@ -169,15 +166,39 @@ _NS:9 - + 3 - MQA - - 2 - + MCAwAA IBCocoaTouchFramework + + + 292 + {320, 44} + + + + _NS:9 + NO + IBCocoaTouchFramework + + NSImage + list_hightlight.png + + + + + 292 + {320, 44} + + + + _NS:9 + + NO + IBCocoaTouchFramework + @@ -205,6 +226,22 @@ 25 + + + backgroundView + + + + 28 + + + + selectedBackgroundView + + + + 29 + onDetails: @@ -269,6 +306,18 @@ chatContentLabel + + 26 + + + selectedBackground + + + 27 + + + background + @@ -283,12 +332,14 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 25 + 29 @@ -341,8 +392,10 @@ YES 3 - {45, 45} - {45, 45} + {131, 131} + {45, 45} + {45, 45} + {640, 88} 1181 diff --git a/Classes/LinphoneUI/UICompositeViewController.h b/Classes/LinphoneUI/UICompositeViewController.h index 0a551c8a7..32c7a3439 100644 --- a/Classes/LinphoneUI/UICompositeViewController.h +++ b/Classes/LinphoneUI/UICompositeViewController.h @@ -40,6 +40,12 @@ @end +@protocol UICompositeViewDelegate + ++ (UICompositeViewDescription*) compositeViewDescription; + +@end + @interface UICompositeViewController : UIViewController { @private UIView *stateBarView; diff --git a/Classes/LinphoneUI/UICompositeViewController.m b/Classes/LinphoneUI/UICompositeViewController.m index 76efd4cde..934d17e7c 100644 --- a/Classes/LinphoneUI/UICompositeViewController.m +++ b/Classes/LinphoneUI/UICompositeViewController.m @@ -24,9 +24,10 @@ - (id)copy { UICompositeViewDescription *copy = [UICompositeViewDescription alloc]; copy->content = self->content; + copy->stateBar = self->stateBar; + copy->stateBarEnabled = self->stateBarEnabled; copy->tabBar = self->tabBar; copy->tabBarEnabled = self->tabBarEnabled; - copy->stateBarEnabled = self->stateBarEnabled; copy->fullscreen = self->fullscreen; return copy; } @@ -156,13 +157,13 @@ } } - if(contentViewController != nil) { + if(oldViewDescription != nil && contentViewController != nil && oldViewDescription->content != currentViewDescription->content) { [UICompositeViewController removeSubView: contentViewController]; } - if(tabBarViewController != nil) { + if(oldViewDescription != nil && tabBarViewController != nil && oldViewDescription->tabBar != currentViewDescription->tabBar) { [UICompositeViewController removeSubView: tabBarViewController]; } - if(stateBarViewController != nil) { + if(oldViewDescription != nil && stateBarViewController != nil && oldViewDescription->stateBar != currentViewDescription->stateBar) { [UICompositeViewController removeSubView: stateBarViewController]; } @@ -253,9 +254,15 @@ // Change view if(description != nil) { - [UICompositeViewController addSubView: contentViewController view:contentView]; - [UICompositeViewController addSubView: tabBarViewController view:tabBarView]; - [UICompositeViewController addSubView: stateBarViewController view:stateBarView]; + if(oldViewDescription == nil || oldViewDescription->content != currentViewDescription->content) { + [UICompositeViewController addSubView: contentViewController view:contentView]; + } + if(oldViewDescription == nil || oldViewDescription->tabBar != currentViewDescription->tabBar) { + [UICompositeViewController addSubView: tabBarViewController view:tabBarView]; + } + if(oldViewDescription == nil || oldViewDescription->stateBar != currentViewDescription->stateBar) { + [UICompositeViewController addSubView: stateBarViewController view:stateBarView]; + } } // Dealloc old view description diff --git a/Classes/LinphoneUI/UIHistoryCell.h b/Classes/LinphoneUI/UIHistoryCell.h index 7500e1c8a..59e4b8ea9 100644 --- a/Classes/LinphoneUI/UIHistoryCell.h +++ b/Classes/LinphoneUI/UIHistoryCell.h @@ -30,6 +30,8 @@ LinphoneCallLog *callLog; } +@property (assign) LinphoneCallLog *callLog; + @property (nonatomic, retain) IBOutlet UIImageView* imageView; @property (nonatomic, retain) IBOutlet UILabel* displayNameLabel; @property (nonatomic, retain) IBOutlet UIButton* detailsButton; @@ -40,7 +42,7 @@ - (IBAction)onDetails:(id) event; - (IBAction)onDelete:(id) event; -- (void)update:(LinphoneCallLog*) callLogs; +- (void)update; - (void)enterEditMode; - (void)exitEditMode; diff --git a/Classes/LinphoneUI/UIHistoryCell.m b/Classes/LinphoneUI/UIHistoryCell.m index 248431b35..3ca3d5592 100644 --- a/Classes/LinphoneUI/UIHistoryCell.m +++ b/Classes/LinphoneUI/UIHistoryCell.m @@ -22,6 +22,7 @@ @implementation UIHistoryCell +@synthesize callLog; @synthesize displayNameLabel; @synthesize imageView; @synthesize deleteButton; @@ -75,21 +76,21 @@ #pragma mark - -- (void)update:(LinphoneCallLog*) aCallLog { - self->callLog = aCallLog; +- (void)update { + // Set up the cell... LinphoneAddress* partyToDisplay; UIImage *image; - if (aCallLog->dir == LinphoneCallIncoming) { - if (aCallLog->status == LinphoneCallSuccess) { + if (callLog->dir == LinphoneCallIncoming) { + if (callLog->status == LinphoneCallSuccess) { image = [UIImage imageNamed:@"call_status_incoming.png"]; } else { image = [UIImage imageNamed:@"call_status_missed.png"]; } - partyToDisplay = aCallLog->from; + partyToDisplay = callLog->from; } else { image = [UIImage imageNamed:@"call_status_outgoing.png"]; - partyToDisplay = aCallLog->to; + partyToDisplay = callLog->to; } const char* username = linphone_address_get_username(partyToDisplay)!=0?linphone_address_get_username(partyToDisplay):""; diff --git a/Classes/LinphoneUI/UIMainBar.m b/Classes/LinphoneUI/UIMainBar.m index 36150e13c..f49ba5535 100644 --- a/Classes/LinphoneUI/UIMainBar.m +++ b/Classes/LinphoneUI/UIMainBar.m @@ -37,34 +37,49 @@ - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [historyButton release]; + [contactsButton release]; + [dialerButton release]; + [settingsButton release]; + [chatButton release]; + [super dealloc]; } #pragma mark - ViewController Functions -- (void)viewDidLoad { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeView:) name:@"LinphoneMainViewChange" object:nil]; - [self update:[[LinphoneManager instance] currentView]]; +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(changeViewEvent:) + name:@"LinphoneMainViewChange" + object:nil]; + [self update:[[PhoneMainView instance] currentView]]; } -- (void)viewDidUnload { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [historyButton release]; - [contactsButton release]; - [dialerButton release]; - [settingsButton release]; - [chatButton release]; +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [[NSNotificationCenter defaultCenter] removeObserver:self + name:@"LinphoneMainViewChange" + object:nil]; } -#pragma mark - -- (void)changeView: (NSNotification*) notif { +#pragma mark - Event Functions + +- (void)changeViewEvent: (NSNotification*) notif { NSNumber *viewNumber = [notif.userInfo objectForKey: @"view"]; if(viewNumber != nil) [self update:[viewNumber intValue]]; } + +#pragma mark - + - (void)update:(PhoneView) view { if(view == PhoneView_History) { historyButton.selected = TRUE; @@ -97,23 +112,23 @@ #pragma mark - Action Functions - (IBAction)onHistoryClick: (id) sender { - [[LinphoneManager instance] changeView:PhoneView_History]; + [[PhoneMainView instance] changeView:PhoneView_History]; } - (IBAction)onContactsClick: (id) event { - [[LinphoneManager instance] changeView:PhoneView_Contacts]; + [[PhoneMainView instance] changeView:PhoneView_Contacts]; } - (IBAction)onDialerClick: (id) event { - [[LinphoneManager instance] changeView:PhoneView_Dialer]; + [[PhoneMainView instance] changeView:PhoneView_Dialer]; } - (IBAction)onSettingsClick: (id) event { - [[LinphoneManager instance] changeView:PhoneView_Settings]; + [[PhoneMainView instance] changeView:PhoneView_Settings]; } - (IBAction)onChatClick: (id) event { - [[LinphoneManager instance] changeView:PhoneView_Chat]; + [[PhoneMainView instance] changeView:PhoneView_Chat]; } diff --git a/Classes/LinphoneUI/UIStateBar.m b/Classes/LinphoneUI/UIStateBar.m index 8df168b19..97ea70e3d 100644 --- a/Classes/LinphoneUI/UIStateBar.m +++ b/Classes/LinphoneUI/UIStateBar.m @@ -47,19 +47,22 @@ NSTimer *callQualityTimer; #pragma mark - ViewController Functions -- (void)viewDidLoad { - [super viewDidLoad]; - - // Set observer - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registrationUpdate:) name:@"LinphoneRegistrationUpdate" object:nil]; +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; // Set callQualityTimer [callQualityImage setHidden: true]; callQualityTimer = [NSTimer scheduledTimerWithTimeInterval:1 - target:self - selector:@selector(callQualityUpdate) - userInfo:nil - repeats:YES]; + target:self + selector:@selector(callQualityUpdate) + userInfo:nil + repeats:YES]; + + // Set observer + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(registrationUpdate:) + name:@"LinphoneRegistrationUpdate" + object:nil]; // Update to default state LinphoneProxyConfig* config = NULL; @@ -68,8 +71,14 @@ NSTimer *callQualityTimer; [self proxyConfigUpdate: config]; } -- (void) viewDidUnload { - [[NSNotificationCenter defaultCenter] removeObserver:self]; +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + // Remove observer + [[NSNotificationCenter defaultCenter] removeObserver:self + name:@"LinphoneRegistrationUpdate" + object:nil]; + [callQualityTimer invalidate]; } @@ -82,6 +91,9 @@ NSTimer *callQualityTimer; [self proxyConfigUpdate:config]; } + +#pragma mark - + - (void)proxyConfigUpdate: (LinphoneProxyConfig*) config { LinphoneRegistrationState state; NSString* message = nil; diff --git a/Classes/LinphoneUI/UIStateBar.xib b/Classes/LinphoneUI/UIStateBar.xib index 7ef29c7d7..ff171f256 100644 --- a/Classes/LinphoneUI/UIStateBar.xib +++ b/Classes/LinphoneUI/UIStateBar.xib @@ -63,7 +63,7 @@ IBCocoaTouchFramework NSImage - status_disconnected.png + led_disconnected.png @@ -269,8 +269,8 @@ YES 3 + {18, 17} {640, 46} - {18, 17} 1181 diff --git a/Classes/Model/ChatModel.h b/Classes/Model/ChatModel.h new file mode 100644 index 000000000..4c2f11963 --- /dev/null +++ b/Classes/Model/ChatModel.h @@ -0,0 +1,47 @@ +/* ChatModel.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 + +@interface ChatModel : NSObject { + @private + NSNumber *chatId; + NSString *localContact; + NSString *remoteContact; + NSNumber *direction; + NSString *message; + NSDate *time; +} + +@property (nonatomic, readonly) NSNumber *chatId; +@property (nonatomic, copy) NSString *localContact; +@property (nonatomic, copy) NSString *remoteContact; +@property (nonatomic, copy) NSNumber *direction; +@property (nonatomic, copy) NSString *message; +@property (nonatomic, copy) NSDate *time; + +- (void) create; ++ (ChatModel*) read:(NSNumber*)id; +- (void) update; +- (void) delete; + ++ (NSArray *) listConversations; ++ (NSArray *) listMessages:(NSString *)contact; + +@end diff --git a/Classes/Model/ChatModel.m b/Classes/Model/ChatModel.m new file mode 100644 index 000000000..5c5ef40ed --- /dev/null +++ b/Classes/Model/ChatModel.m @@ -0,0 +1,229 @@ +/* ChatModel.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 "ChatModel.h" +#import "LinphoneManager.h" + +@implementation ChatModel + +@synthesize chatId; +@synthesize localContact; +@synthesize remoteContact; +@synthesize message; +@synthesize direction; +@synthesize time; + + +#pragma mark - Lifecycle Functions + +- (id)initWithData:(sqlite3_stmt *)sqlStatement { + self = [super init]; + if (self != nil) { + self->chatId = [[NSNumber alloc] initWithInt: sqlite3_column_int(sqlStatement, 0)]; + self.localContact = [NSString stringWithUTF8String: (const char*) sqlite3_column_text(sqlStatement, 1)]; + self.remoteContact = [NSString stringWithUTF8String: (const char*) sqlite3_column_text(sqlStatement, 2)]; + self.direction = [NSNumber numberWithInt:sqlite3_column_int(sqlStatement, 3)]; + self.message = [NSString stringWithUTF8String: (const char*) sqlite3_column_text(sqlStatement, 4)]; + self.time = [NSDate dateWithTimeIntervalSince1970:sqlite3_column_int(sqlStatement, 5)]; + } + return self; +} + +- (void)dealloc { + [chatId release]; + [localContact release]; + [remoteContact release]; + [message release]; + [direction release]; + [time release]; + + [super dealloc]; +} + + +#pragma mark - CRUD Functions + +- (void)create { + sqlite3* database = [[LinphoneManager instance] database]; + if(database == NULL) { + NSLog(@"Database not ready"); + return; + } + const char *sql = [[NSString stringWithFormat:@"INSERT INTO chat (localContact, remoteContact, direction, message, time) VALUES (\"%@\", \"%@\", %i, \"%@\", %i)", + localContact, remoteContact, [direction intValue], message, [time timeIntervalSince1970]] UTF8String]; + sqlite3_stmt *sqlStatement; + if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { + NSLog(@"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)); + return; + } + + if (sqlite3_step(sqlStatement) != SQLITE_DONE) { + NSLog(@"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)); + sqlite3_finalize(sqlStatement); + } +} + ++ (ChatModel*)read:(NSNumber*)chatId { + sqlite3* database = [[LinphoneManager instance] database]; + if(database == NULL) { + NSLog(@"Database not ready"); + return nil; + } + + const char *sql = [[NSString stringWithFormat:@"SELECT id, localContact, remoteContact, direction, message, time FROM chat WHERE id=%@", + chatId] UTF8String]; + sqlite3_stmt *sqlStatement; + if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { + NSLog(@"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)); + return nil; + } + + ChatModel* line = nil; + int err = sqlite3_step(sqlStatement); + if (err == SQLITE_ROW) { + line = [[ChatModel alloc] initWithData:sqlStatement]; + } else if (err != SQLITE_DONE) { + NSLog(@"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)); + sqlite3_finalize(sqlStatement); + return nil; + } + + sqlite3_finalize(sqlStatement); + return line; +} + +- (void)update { + sqlite3* database = [[LinphoneManager instance] database]; + if(database == NULL) { + NSLog(@"Database not ready"); + return; + } + + const char *sql = [[NSString stringWithFormat:@"UPDATE chat SET localContact=\"%@\", remoteContact=\"%@\", direction=%i, message=\"%@\", time=%i WHERE id=%@", + localContact, remoteContact, [direction intValue], message, [time timeIntervalSince1970], chatId] UTF8String]; + sqlite3_stmt *sqlStatement; + if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { + NSLog(@"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)); + return; + } + + if (sqlite3_step(sqlStatement) != SQLITE_DONE) { + NSLog(@"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)); + sqlite3_finalize(sqlStatement); + return; + } + + sqlite3_finalize(sqlStatement); +} + +- (void)delete { + sqlite3* database = [[LinphoneManager instance] database]; + if(database == NULL) { + NSLog(@"Database not ready"); + return; + } + + const char *sql = [[NSString stringWithFormat:@"DELETE chat WHERE id=%@", + chatId] UTF8String]; + sqlite3_stmt *sqlStatement; + if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { + NSLog(@"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)); + return; + } + + if (sqlite3_step(sqlStatement) != SQLITE_DONE) { + NSLog(@"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)); + sqlite3_finalize(sqlStatement); + return; + } + + sqlite3_finalize(sqlStatement); +} + + +#pragma mark - + ++ (NSArray *)listConversations { + sqlite3* database = [[LinphoneManager instance] database]; + if(database == NULL) { + NSLog(@"Database not ready"); + return [[[NSArray alloc] init] autorelease]; + } + + const char *sql = "SELECT id, localContact, remoteContact, direction, message, time FROM chat GROUP BY remoteContact ORDER BY time DESC"; + sqlite3_stmt *sqlStatement; + if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { + NSLog(@"Can't execute the query: %s (%s)", sql, sqlite3_errmsg(database)); + return [[[NSArray alloc] init] autorelease]; + } + + NSMutableArray *array = [[NSMutableArray alloc] init]; + int err; + while ((err = sqlite3_step(sqlStatement)) == SQLITE_ROW) { + ChatModel *line = [[ChatModel alloc] initWithData:sqlStatement]; + [array addObject:line]; + } + + if (err != SQLITE_DONE) { + NSLog(@"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)); + return [[[NSArray alloc] init] autorelease]; + } + + sqlite3_finalize(sqlStatement); + + NSArray *fArray = [NSArray arrayWithArray: array]; + [array release]; + return fArray; +} + ++ (NSArray *)listMessages:(NSString *)contact { + sqlite3* database = [[LinphoneManager instance] database]; + if(database == NULL) { + NSLog(@"Database not ready"); + 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", + contact] UTF8String]; + sqlite3_stmt *sqlStatement; + if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { + NSLog(@"Can't execute the query: %s (%s)", sql, sqlite3_errmsg(database)); + return [[[NSArray alloc] init] autorelease]; + } + + NSMutableArray *array = [[NSMutableArray alloc] init]; + int err; + while ((err = sqlite3_step(sqlStatement)) == SQLITE_ROW) { + ChatModel *line = [[ChatModel alloc] initWithData:sqlStatement]; + [array addObject:line]; + } + + if (err != SQLITE_DONE) { + NSLog(@"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)); + return [[[NSArray alloc] init] autorelease]; + } + + sqlite3_finalize(sqlStatement); + + NSArray *fArray = [NSArray arrayWithArray: array]; + [array release]; + return fArray; +} + +@end diff --git a/Classes/MoreViewController.h b/Classes/MoreViewController.h index 4cc2a28d4..896a3a003 100644 --- a/Classes/MoreViewController.h +++ b/Classes/MoreViewController.h @@ -20,7 +20,7 @@ #import @class ConsoleViewController; -@interface MoreViewController : UITableViewController { +@interface MoreViewController : UITableViewController { bool isLogViewEnabled; diff --git a/Classes/PhoneMainView.h b/Classes/PhoneMainView.h index b8dc86c26..3bb0af14d 100644 --- a/Classes/PhoneMainView.h +++ b/Classes/PhoneMainView.h @@ -24,6 +24,20 @@ #import "UICompositeViewController.h" #import "UIModalViewController.h" +typedef enum _PhoneView { + PhoneView_Wizard, + PhoneView_FirstLogin, + PhoneView_Dialer, + PhoneView_History, + PhoneView_Settings, + PhoneView_Chat, + PhoneView_ChatRoom, + PhoneView_Contacts, + PhoneView_InCall, + PhoneView_IncomingCall, + PhoneView_END +} PhoneView; + @interface PhoneMainView : UIViewController { @private UICompositeViewController *mainViewController; @@ -31,14 +45,28 @@ NSMutableArray *modalControllers; NSMutableDictionary *viewDescriptions; - PhoneView currentPhoneView; - + UIActionSheet *incomingCallActionSheet; UIActionSheet *batteryActionSheet; int loadCount; + + PhoneView currentView; + NSMutableArray* viewStack; } @property (nonatomic, retain) IBOutlet UICompositeViewController *mainViewController; +- (void)changeView:(PhoneView)view; +- (void)changeView:(PhoneView)view push:(BOOL)push; +- (void)changeView:(PhoneView)view dict:(NSDictionary *)dict; +- (void)changeView:(PhoneView)view dict:(NSDictionary *)dict push:(BOOL)push; +- (void)popView; +- (void)popView:(NSDictionary *)dict; +- (void)showTabBar:(BOOL)show; +- (void)fullScreen:(BOOL)enabled; +- (PhoneView)currentView; + ++ (PhoneMainView*) instance; + @end diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index 1a6cecd47..7b2cc2ef4 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -24,8 +24,20 @@ #import "FirstLoginViewController.h" #import "IncomingCallViewController.h" +#import "ChatRoomViewController.h" +#import "ChatViewController.h" +#import "DialerViewController.h" +#import "ContactsViewController.h" +#import "HistoryViewController.h" +#import "InCallViewController.h" +#import "SettingsViewController.h" +#import "FirstLoginViewController.h" +#import "WizardViewController.h" + #import "AbstractCall.h" +static PhoneMainView* phoneMainViewInstance=nil; + @implementation PhoneMainView @synthesize mainViewController; @@ -34,7 +46,10 @@ #pragma mark - Lifecycle Functions - (void)initPhoneMainView { - currentPhoneView = -1; + assert (!phoneMainViewInstance); + phoneMainViewInstance = self; + currentView = -1; + viewStack = [[NSMutableArray alloc] init]; loadCount = 0; // For avoiding IOS 4 bug // Init view descriptions @@ -77,6 +92,8 @@ [modalControllers removeAllObjects]; [modalControllers release]; + [viewStack release]; + [super dealloc]; } @@ -91,110 +108,22 @@ [super viewDidLoad]; [[self view] addSubview: mainViewController.view]; - // - // Main View - // - UICompositeViewDescription *dialerDescription = [UICompositeViewDescription alloc]; - dialerDescription->content = @"DialerViewController"; - dialerDescription->tabBar = @"UIMainBar"; - dialerDescription->tabBarEnabled = true; - dialerDescription->stateBar = @"UIStateBar"; - dialerDescription->stateBarEnabled = true; - dialerDescription->fullscreen = false; - [viewDescriptions setObject:dialerDescription forKey:[NSNumber numberWithInt: PhoneView_Dialer]]; - - - // - // Contacts View - // - UICompositeViewDescription *contactsDescription = [UICompositeViewDescription alloc]; - contactsDescription->content = @"ContactsViewController"; - contactsDescription->tabBar = @"UIMainBar"; - contactsDescription->tabBarEnabled = true; - contactsDescription->stateBar = nil; - contactsDescription->stateBarEnabled = false; - contactsDescription->fullscreen = false; - [viewDescriptions setObject:contactsDescription forKey:[NSNumber numberWithInt: PhoneView_Contacts]]; - - - // - // Call History View - // - UICompositeViewDescription *historyDescription = [UICompositeViewDescription alloc]; - historyDescription->content = @"HistoryViewController"; - historyDescription->tabBar = @"UIMainBar"; - historyDescription->tabBarEnabled = true; - historyDescription->stateBar = nil; - historyDescription->stateBarEnabled = false; - historyDescription->fullscreen = false; - [viewDescriptions setObject:historyDescription forKey:[NSNumber numberWithInt: PhoneView_History]]; - - // - // InCall View - // - UICompositeViewDescription *inCallDescription = [UICompositeViewDescription alloc]; - inCallDescription->content = @"InCallViewController"; - inCallDescription->tabBar = @"UICallBar"; - inCallDescription->tabBarEnabled = true; - inCallDescription->stateBar = @"UIStateBar"; - inCallDescription->stateBarEnabled = true; - inCallDescription->fullscreen = false; - [viewDescriptions setObject:inCallDescription forKey:[NSNumber numberWithInt: PhoneView_InCall]]; - - - // - // Settings View - // - UICompositeViewDescription *settingsDescription = [UICompositeViewDescription alloc]; - settingsDescription->content = @"SettingsViewController"; - settingsDescription->tabBar = @"UIMainBar"; - settingsDescription->tabBarEnabled = true; - settingsDescription->stateBar = nil; - settingsDescription->stateBarEnabled = false; - settingsDescription->fullscreen = false; - [viewDescriptions setObject:settingsDescription forKey:[NSNumber numberWithInt: PhoneView_Settings]]; - - // - // Chat View - // - UICompositeViewDescription *chatDescription = [UICompositeViewDescription alloc]; - chatDescription->content = @"ChatViewController"; - chatDescription->tabBar = @"UIMainBar"; - chatDescription->tabBarEnabled = true; - chatDescription->stateBar = nil; - chatDescription->stateBarEnabled = false; - chatDescription->fullscreen = false; - [viewDescriptions setObject:chatDescription forKey:[NSNumber numberWithInt: PhoneView_Chat]]; - - // - // FirstLogin View - // - UICompositeViewDescription *firstLoginDescription = [UICompositeViewDescription alloc]; - firstLoginDescription->content = @"FirstLoginViewController"; - firstLoginDescription->tabBar = nil; - firstLoginDescription->tabBarEnabled = false; - firstLoginDescription->stateBar = nil; - firstLoginDescription->stateBarEnabled = false; - firstLoginDescription->fullscreen = false; - [viewDescriptions setObject:firstLoginDescription forKey:[NSNumber numberWithInt: PhoneView_FirstLogin]]; - - // - // Wizard View - // - UICompositeViewDescription *wizardDescription = [UICompositeViewDescription alloc]; - wizardDescription->content = @"WizardViewController"; - wizardDescription->tabBar = nil; - wizardDescription->tabBarEnabled = false; - wizardDescription->stateBar = nil; - wizardDescription->stateBarEnabled = false; - wizardDescription->fullscreen = false; - [viewDescriptions setObject:wizardDescription forKey:[NSNumber numberWithInt: PhoneView_Wizard]]; + // Init descriptions + [viewDescriptions setObject:[ChatRoomViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_ChatRoom]]; + [viewDescriptions setObject:[ChatViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_Chat]]; + [viewDescriptions setObject:[DialerViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_Dialer]]; + [viewDescriptions setObject:[ContactsViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_Contacts]]; + [viewDescriptions setObject:[HistoryViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_History]]; + [viewDescriptions setObject:[InCallViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_InCall]]; + [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]]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; // Set observers - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(changeView:) - name:@"LinphoneMainViewChange" - object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callUpdate:) name:@"LinphoneCallUpdate" @@ -203,17 +132,31 @@ selector:@selector(registrationUpdate:) name:@"LinphoneRegistrationUpdate" object:nil]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil]; } +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + // Remove observers + [[NSNotificationCenter defaultCenter] removeObserver:self + name:@"LinphoneCallUpdate" + object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:@"LinphoneRegistrationUpdate" + object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIDeviceBatteryLevelDidChangeNotification + object:nil]; +} + - (void)viewDidUnload { [super viewDidUnload]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; - + // Avoid IOS 4 bug self->loadCount--; } @@ -271,7 +214,7 @@ case LinphoneCallConnected: case LinphoneCallUpdated: { - [[LinphoneManager instance] changeView:PhoneView_InCall]; + [self changeView:PhoneView_InCall]; break; } case LinphoneCallUpdatedByRemote: @@ -280,7 +223,7 @@ const LinphoneCallParams* remote = linphone_call_get_remote_params(call); if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) { - [[LinphoneManager instance] changeView:PhoneView_InCall]; + [self changeView:PhoneView_InCall]; } break; } @@ -299,15 +242,15 @@ [[[NSArray alloc] initWithObjects: [NSNumber numberWithInt: FALSE], nil] autorelease] , @"setTransferMode:", nil] autorelease]; - [[LinphoneManager instance] changeView:PhoneView_Dialer dict:dict]; + [self changeView:PhoneView_Dialer dict:dict]; } else { - [[LinphoneManager instance] changeView:PhoneView_InCall]; + [self changeView:PhoneView_InCall]; } break; } case LinphoneCallStreamsRunning: { - [[LinphoneManager instance] changeView:PhoneView_InCall]; + [self changeView:PhoneView_InCall]; break; } default: @@ -318,12 +261,27 @@ #pragma mark - -- (CATransition*)getTransition:(PhoneView)old new:(PhoneView)new { ++ (CATransition*)getBackwardTransition { CATransition* trans = [CATransition animation]; [trans setType:kCATransitionPush]; [trans setDuration:0.35]; [trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; + [trans setSubtype:kCATransitionFromLeft]; + return trans; +} + ++ (CATransition*)getForwardTransition { + CATransition* trans = [CATransition animation]; + [trans setType:kCATransitionPush]; + [trans setDuration:0.35]; + [trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; + [trans setSubtype:kCATransitionFromRight]; + + return trans; +} + ++ (CATransition*)getTransition:(PhoneView)old new:(PhoneView)new { bool left = false; if(old == PhoneView_Chat) { @@ -351,44 +309,80 @@ } if(left) { - [trans setSubtype:kCATransitionFromLeft]; + return [PhoneMainView getBackwardTransition]; } else { - [trans setSubtype:kCATransitionFromRight]; + return [PhoneMainView getForwardTransition]; } - - return trans; } -- (void)changeView: (NSNotification*) notif { - NSNumber *viewId = [notif.userInfo objectForKey: @"view"]; - NSNumber *tabBar = [notif.userInfo objectForKey: @"tabBar"]; - NSNumber *fullscreen = [notif.userInfo objectForKey: @"fullscreen"]; - - // Check view change - if(viewId != nil) { - PhoneView view = [viewId intValue]; - UICompositeViewDescription* description = [viewDescriptions objectForKey:[NSNumber numberWithInt: view]]; - if(description == nil) - return; - if(view != currentPhoneView) { - [mainViewController setViewTransition:[self getTransition:currentPhoneView new:view]]; - [mainViewController changeView:description]; - currentPhoneView = view; - } ++ (PhoneMainView *) instance { + return phoneMainViewInstance; +} + +- (void) showTabBar:(BOOL) show { + [mainViewController setToolBarHidden:!show]; +} + +- (void)fullScreen:(BOOL) enabled { + [mainViewController setFullScreen:enabled]; +} + +- (void)changeView:(PhoneView)view { + [self changeView:view dict:nil push:FALSE]; +} + +- (void)changeView:(PhoneView)view dict:(NSDictionary *)dict { + [self changeView:view dict:dict push:FALSE]; +} + +- (void)changeView:(PhoneView)view push:(BOOL)push { + [self changeView:view dict:nil push:push]; +} + +- (void)changeView:(PhoneView)view dict:(NSDictionary *)dict push:(BOOL)push { + if(push && currentView != -1) { + [viewStack addObject:[NSNumber numberWithInt: currentView]]; + } else { + [viewStack removeAllObjects]; } + [self _changeView:view dict:dict transition:nil]; +} + +- (void)_changeView:(PhoneView)view dict:(NSDictionary *)dict transition:(CATransition*)transition { + UICompositeViewDescription* description = [viewDescriptions objectForKey:[NSNumber numberWithInt: view]]; + if(description == nil) + return; - if(tabBar != nil) { - [mainViewController setToolBarHidden:![tabBar boolValue]]; - } - - if(fullscreen != nil) { - [mainViewController setFullScreen:[fullscreen boolValue]]; - } + if(view != currentView) { + if(transition == nil) + transition = [PhoneMainView getTransition:currentView new:view]; + [mainViewController setViewTransition:transition]; + [mainViewController changeView:description]; + currentView = view; + } // Call abstractCall - NSDictionary *dict = [notif.userInfo objectForKey: @"args"]; if(dict != nil) [AbstractCall call:[mainViewController getCurrentViewController] dict:dict]; + + NSDictionary* mdict = [NSMutableDictionary dictionaryWithObject: [NSNumber numberWithInt:currentView] forKey:@"view"]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"LinphoneMainViewChange" object:self userInfo:mdict]; +} + +- (void)popView { + [self popView:nil]; +} + +- (void)popView:(NSDictionary *)dict { + if([viewStack count] > 0) { + PhoneView view = [[viewStack lastObject] intValue]; + [viewStack removeLastObject]; + [self _changeView:view dict:dict transition:[PhoneMainView getBackwardTransition]]; + } +} + +- (PhoneView)currentView { + return currentView; } - (void)displayCallError:(LinphoneCall*) call message:(NSString*) message { @@ -461,7 +455,7 @@ } } else { IncomingCallViewController *controller = [[IncomingCallViewController alloc] init]; - [controller update:call]; + [controller setCall:call]; [self addModalViewController:controller]; } } diff --git a/Classes/SettingsViewController.h b/Classes/SettingsViewController.h index c6b0b4754..7bc3df627 100644 --- a/Classes/SettingsViewController.h +++ b/Classes/SettingsViewController.h @@ -19,9 +19,10 @@ #import +#import "UICompositeViewController.h" #import "IASKAppSettingsViewController.h" -@interface SettingsViewController: UIViewController { +@interface SettingsViewController: UIViewController { IASKAppSettingsViewController *settingsController; UINavigationController *navigationController; } diff --git a/Classes/SettingsViewController.m b/Classes/SettingsViewController.m index bd5f34100..41e117729 100644 --- a/Classes/SettingsViewController.m +++ b/Classes/SettingsViewController.m @@ -32,6 +32,20 @@ } +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription*) compositeViewDescription { + UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"SettingsViewController"; + description->tabBar = @"UIMainBar"; + description->tabBarEnabled = true; + description->stateBar = nil; + description->stateBarEnabled = false; + description->fullscreen = false; + return description; +} + + #pragma mark - ViewController Functions - (void)viewDidLoad { diff --git a/Classes/WizardViewController.h b/Classes/WizardViewController.h index d1115d1f4..0326f5b07 100644 --- a/Classes/WizardViewController.h +++ b/Classes/WizardViewController.h @@ -19,7 +19,9 @@ #import -@interface WizardViewController : UIViewController { +#import "UICompositeViewController.h" + +@interface WizardViewController : UIViewController { UIView *contentView; UIView *welcomeView; diff --git a/Classes/WizardViewController.m b/Classes/WizardViewController.m index e3b1c4cb2..226f61ece 100644 --- a/Classes/WizardViewController.m +++ b/Classes/WizardViewController.m @@ -23,6 +23,8 @@ #import "LinphoneManager.h" +#import "PhoneMainView.h" + typedef enum _ViewElement { ViewElement_Username = 100, ViewElement_Password = 101, @@ -74,6 +76,20 @@ typedef enum _ViewElement { } +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription*) compositeViewDescription { +UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"WizardViewController"; + description->tabBar = nil; + description->tabBarEnabled = false; + description->stateBar = nil; + description->stateBarEnabled = false; + description->fullscreen = false; + return description; +} + + #pragma mark - ViewController Functions - (void)viewDidLoad { @@ -168,7 +184,7 @@ typedef enum _ViewElement { } - (IBAction)onCancelClick:(id)sender { - [[LinphoneManager instance] changeView:PhoneView_Dialer]; + [[PhoneMainView instance] changeView:PhoneView_Dialer]; } - (IBAction)onCreateAccountClick:(id)sender { diff --git a/Resources/chat_back_default.png b/Resources/chat_back_default.png new file mode 100644 index 000000000..3c90a7bb6 Binary files /dev/null and b/Resources/chat_back_default.png differ diff --git a/Resources/chat_back_over.png b/Resources/chat_back_over.png new file mode 100644 index 000000000..ce56ede38 Binary files /dev/null and b/Resources/chat_back_over.png differ diff --git a/Resources/chat_field.png b/Resources/chat_field.png new file mode 100644 index 000000000..17a1bee8d Binary files /dev/null and b/Resources/chat_field.png differ diff --git a/Resources/chat_ok_default.png b/Resources/chat_ok_default.png new file mode 100644 index 000000000..0c49ac3d5 Binary files /dev/null and b/Resources/chat_ok_default.png differ diff --git a/Resources/chat_ok_over.png b/Resources/chat_ok_over.png new file mode 100644 index 000000000..4fe6248f8 Binary files /dev/null and b/Resources/chat_ok_over.png differ diff --git a/Resources/chat_send_default.png b/Resources/chat_send_default.png new file mode 100644 index 000000000..1bee48a2f Binary files /dev/null and b/Resources/chat_send_default.png differ diff --git a/Resources/chat_send_disabled.png b/Resources/chat_send_disabled.png new file mode 100644 index 000000000..e16748ec1 Binary files /dev/null and b/Resources/chat_send_disabled.png differ diff --git a/Resources/chat_send_over.png b/Resources/chat_send_over.png new file mode 100644 index 000000000..a130fe1bf Binary files /dev/null and b/Resources/chat_send_over.png differ diff --git a/Resources/database.sqlite b/Resources/database.sqlite new file mode 100644 index 000000000..d52fcbd6e Binary files /dev/null and b/Resources/database.sqlite differ diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 930be9325..bd35fda31 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -223,6 +223,15 @@ D32648451588F6FC00930C67 /* UIToggleButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D32648431588F6FB00930C67 /* UIToggleButton.m */; }; D32942A41594C94300556A1C /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D32942A31594C94200556A1C /* SettingsViewController.xib */; }; D32942A51594C94300556A1C /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D32942A31594C94200556A1C /* SettingsViewController.xib */; }; + D32B6E2415A5B2020033019F /* chat_send_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D32B6E2315A5B2020033019F /* chat_send_disabled.png */; }; + D32B6E2515A5B2020033019F /* chat_send_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D32B6E2315A5B2020033019F /* chat_send_disabled.png */; }; + D32B6E2915A5BC440033019F /* ChatRoomTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D32B6E2815A5BC430033019F /* ChatRoomTableViewController.m */; }; + D32B6E2A15A5BC440033019F /* ChatRoomTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D32B6E2815A5BC430033019F /* ChatRoomTableViewController.m */; }; + D32B6E2C15A5C0800033019F /* database.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D32B6E2B15A5C0800033019F /* database.sqlite */; }; + D32B6E2D15A5C0800033019F /* database.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D32B6E2B15A5C0800033019F /* database.sqlite */; }; + D32B6E2F15A5C0AC0033019F /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D32B6E2E15A5C0AC0033019F /* libsqlite3.dylib */; }; + D32B6E3815A5C2430033019F /* ChatModel.m in Sources */ = {isa = PBXBuildFile; fileRef = D32B6E3715A5C2430033019F /* ChatModel.m */; }; + D32B6E3915A5C2430033019F /* ChatModel.m in Sources */ = {isa = PBXBuildFile; fileRef = D32B6E3715A5C2430033019F /* ChatModel.m */; }; D32B9DFC15A2F131000B6DEC /* FastAddressBook.m in Sources */ = {isa = PBXBuildFile; fileRef = D32B9DFB15A2F131000B6DEC /* FastAddressBook.m */; }; D32B9DFD15A2F131000B6DEC /* FastAddressBook.m in Sources */ = {isa = PBXBuildFile; fileRef = D32B9DFB15A2F131000B6DEC /* FastAddressBook.m */; }; D3432A62158A4446001C6B0B /* led_connected.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A5C158A4446001C6B0B /* led_connected.png */; }; @@ -423,6 +432,16 @@ D3A55FBD15877E5E003FD403 /* UIContactCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D3A55FBB15877E5E003FD403 /* UIContactCell.m */; }; D3A55FBF15877E69003FD403 /* UIContactCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3A55FBE15877E69003FD403 /* UIContactCell.xib */; }; D3A55FC015877E69003FD403 /* UIContactCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3A55FBE15877E69003FD403 /* UIContactCell.xib */; }; + D3B9A3DF15A58C450096EA4E /* chat_field.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DA15A58C440096EA4E /* chat_field.png */; }; + D3B9A3E015A58C450096EA4E /* chat_field.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DA15A58C440096EA4E /* chat_field.png */; }; + D3B9A3E115A58C450096EA4E /* chat_ok_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DB15A58C440096EA4E /* chat_ok_default.png */; }; + D3B9A3E215A58C450096EA4E /* chat_ok_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DB15A58C440096EA4E /* chat_ok_default.png */; }; + D3B9A3E315A58C450096EA4E /* chat_ok_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DC15A58C440096EA4E /* chat_ok_over.png */; }; + D3B9A3E415A58C450096EA4E /* chat_ok_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DC15A58C440096EA4E /* chat_ok_over.png */; }; + D3B9A3E515A58C450096EA4E /* chat_send_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DD15A58C440096EA4E /* chat_send_default.png */; }; + D3B9A3E615A58C450096EA4E /* chat_send_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DD15A58C440096EA4E /* chat_send_default.png */; }; + D3B9A3E715A58C450096EA4E /* chat_send_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DE15A58C450096EA4E /* chat_send_over.png */; }; + D3B9A3E815A58C450096EA4E /* chat_send_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DE15A58C450096EA4E /* chat_send_over.png */; }; D3C2814B15A2D38D0098AA42 /* dialer_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C2814A15A2D38D0098AA42 /* dialer_selected.png */; }; D3C2814C15A2D38D0098AA42 /* dialer_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C2814A15A2D38D0098AA42 /* dialer_selected.png */; }; D3C2815215A2D64A0098AA42 /* numpad_star_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C2815115A2D64A0098AA42 /* numpad_star_over.png */; }; @@ -525,6 +544,14 @@ D3F34F311599B008005BE94F /* avatar_shadow.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F34F2F1599B008005BE94F /* avatar_shadow.png */; }; D3F34F351599C354005BE94F /* UIModalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F34F341599C354005BE94F /* UIModalViewController.m */; }; D3F34F361599C354005BE94F /* UIModalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F34F341599C354005BE94F /* UIModalViewController.m */; }; + D3F795D615A582810077328B /* ChatRoomViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F795D415A582800077328B /* ChatRoomViewController.m */; }; + D3F795D715A582810077328B /* ChatRoomViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F795D415A582800077328B /* ChatRoomViewController.m */; }; + D3F795D815A582810077328B /* ChatRoomViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3F795D515A582800077328B /* ChatRoomViewController.xib */; }; + D3F795D915A582810077328B /* ChatRoomViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3F795D515A582800077328B /* ChatRoomViewController.xib */; }; + D3F795DD15A5831C0077328B /* chat_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F795DB15A5831C0077328B /* chat_back_default.png */; }; + D3F795DE15A5831C0077328B /* chat_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F795DB15A5831C0077328B /* chat_back_default.png */; }; + D3F795DF15A5831C0077328B /* chat_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F795DC15A5831C0077328B /* chat_back_over.png */; }; + D3F795E015A5831C0077328B /* chat_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F795DC15A5831C0077328B /* chat_back_over.png */; }; D3F83EEC1582021700336684 /* InCallViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F83EEA1582021700336684 /* InCallViewController.m */; }; D3F83EED1582021700336684 /* InCallViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F83EEA1582021700336684 /* InCallViewController.m */; }; D3F83EEE1582021700336684 /* InCallViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EEB1582021700336684 /* InCallViewController.xib */; }; @@ -979,6 +1006,13 @@ D32648421588F6FA00930C67 /* UIToggleButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIToggleButton.h; sourceTree = ""; }; D32648431588F6FB00930C67 /* UIToggleButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIToggleButton.m; sourceTree = ""; }; D32942A31594C94200556A1C /* SettingsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsViewController.xib; sourceTree = ""; }; + D32B6E2315A5B2020033019F /* chat_send_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_send_disabled.png; path = Resources/chat_send_disabled.png; sourceTree = ""; }; + D32B6E2715A5BC430033019F /* ChatRoomTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatRoomTableViewController.h; sourceTree = ""; }; + D32B6E2815A5BC430033019F /* ChatRoomTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatRoomTableViewController.m; sourceTree = ""; }; + D32B6E2B15A5C0800033019F /* database.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; name = database.sqlite; path = Resources/database.sqlite; sourceTree = ""; }; + D32B6E2E15A5C0AC0033019F /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; + D32B6E3615A5C2430033019F /* ChatModel.h */ = {isa = PBXFileReference; fileEncoding = 4; name = ChatModel.h; path = Model/ChatModel.h; sourceTree = ""; }; + D32B6E3715A5C2430033019F /* ChatModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ChatModel.m; path = Model/ChatModel.m; sourceTree = ""; }; D32B9DFA15A2F131000B6DEC /* FastAddressBook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FastAddressBook.h; path = Utils/FastAddressBook.h; sourceTree = ""; }; D32B9DFB15A2F131000B6DEC /* FastAddressBook.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FastAddressBook.m; path = Utils/FastAddressBook.m; sourceTree = ""; }; D3432A5C158A4446001C6B0B /* led_connected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = led_connected.png; path = Resources/led_connected.png; sourceTree = ""; }; @@ -1115,6 +1149,11 @@ D3A55FBA15877E5E003FD403 /* UIContactCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIContactCell.h; sourceTree = ""; }; D3A55FBB15877E5E003FD403 /* UIContactCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIContactCell.m; sourceTree = ""; }; D3A55FBE15877E69003FD403 /* UIContactCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UIContactCell.xib; sourceTree = ""; }; + D3B9A3DA15A58C440096EA4E /* chat_field.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_field.png; path = Resources/chat_field.png; sourceTree = ""; }; + D3B9A3DB15A58C440096EA4E /* chat_ok_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_ok_default.png; path = Resources/chat_ok_default.png; sourceTree = ""; }; + D3B9A3DC15A58C440096EA4E /* chat_ok_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_ok_over.png; path = Resources/chat_ok_over.png; sourceTree = ""; }; + D3B9A3DD15A58C440096EA4E /* chat_send_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_send_default.png; path = Resources/chat_send_default.png; sourceTree = ""; }; + D3B9A3DE15A58C450096EA4E /* chat_send_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_send_over.png; path = Resources/chat_send_over.png; sourceTree = ""; }; D3C2814A15A2D38D0098AA42 /* dialer_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_selected.png; path = Resources/dialer_selected.png; sourceTree = ""; }; D3C2815115A2D64A0098AA42 /* numpad_star_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_star_over.png; path = Resources/numpad_star_over.png; sourceTree = ""; }; D3C714B2159DB84400705B8E /* toy-mono.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = "toy-mono.wav"; path = "Resources/toy-mono.wav"; sourceTree = ""; }; @@ -1175,6 +1214,11 @@ D3F34F2F1599B008005BE94F /* avatar_shadow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = avatar_shadow.png; path = Resources/avatar_shadow.png; sourceTree = ""; }; D3F34F331599C354005BE94F /* UIModalViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIModalViewController.h; sourceTree = ""; }; D3F34F341599C354005BE94F /* UIModalViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIModalViewController.m; sourceTree = ""; }; + D3F795D315A582800077328B /* ChatRoomViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatRoomViewController.h; sourceTree = ""; }; + D3F795D415A582800077328B /* ChatRoomViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatRoomViewController.m; sourceTree = ""; }; + D3F795D515A582800077328B /* ChatRoomViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ChatRoomViewController.xib; sourceTree = ""; }; + D3F795DB15A5831C0077328B /* chat_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_back_default.png; path = Resources/chat_back_default.png; sourceTree = ""; }; + D3F795DC15A5831C0077328B /* chat_back_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_back_over.png; path = Resources/chat_back_over.png; sourceTree = ""; }; D3F83EE91582021700336684 /* InCallViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InCallViewController.h; sourceTree = ""; }; D3F83EEA1582021700336684 /* InCallViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InCallViewController.m; sourceTree = ""; }; D3F83EEB1582021700336684 /* InCallViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = InCallViewController.xib; sourceTree = ""; }; @@ -1233,6 +1277,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D32B6E2F15A5C0AC0033019F /* libsqlite3.dylib in Frameworks */, D37DC7181594AF3400B2A5EB /* MessageUI.framework in Frameworks */, 340751971506459A00B89C47 /* CoreTelephony.framework in Frameworks */, 226CDADF14E2D0B800513B67 /* libbcg729.a in Frameworks */, @@ -1331,8 +1376,14 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( + D32B6E3515A5C2200033019F /* Model */, 340751E4150E4D0200B89C47 /* CallDelegate.h */, 2211DBBB14769C8200DEE054 /* CallDelegate.m */, + D32B6E2715A5BC430033019F /* ChatRoomTableViewController.h */, + D32B6E2815A5BC430033019F /* ChatRoomTableViewController.m */, + D3F795D315A582800077328B /* ChatRoomViewController.h */, + D3F795D415A582800077328B /* ChatRoomViewController.m */, + D3F795D515A582800077328B /* ChatRoomViewController.xib */, D3EA540B1598528B0037DC6B /* ChatTableViewController.h */, D3EA540C1598528B0037DC6B /* ChatTableViewController.m */, D35E7594159460560066B1C1 /* ChatViewController.h */, @@ -1747,6 +1798,7 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( + D32B6E2E15A5C0AC0033019F /* libsqlite3.dylib */, 2258633C11410BAC00C5A737 /* README */, 22276E8013C73D3100210156 /* libavcodec.a */, 22276E8113C73D3100210156 /* libavutil.a */, @@ -1867,11 +1919,19 @@ D36C43CD158F2F370048BA40 /* cell_conference.png */, D3EA5401159852080037DC6B /* chat_add_default.png */, D3EA5402159852080037DC6B /* chat_add_over.png */, + D3F795DB15A5831C0077328B /* chat_back_default.png */, + D3F795DC15A5831C0077328B /* chat_back_over.png */, D38327F11580FE3A00FA0D23 /* chat_default.png */, D3EA53FF159852080037DC6B /* chat_edit_default.png */, D3EA5400159852080037DC6B /* chat_edit_over.png */, + D3B9A3DA15A58C440096EA4E /* chat_field.png */, + D3B9A3DB15A58C440096EA4E /* chat_ok_default.png */, + D3B9A3DC15A58C440096EA4E /* chat_ok_over.png */, D38327FF158100E400FA0D23 /* chat_over.png */, D38327F21580FE3A00FA0D23 /* chat_selected.png */, + D3B9A3DD15A58C440096EA4E /* chat_send_default.png */, + D32B6E2315A5B2020033019F /* chat_send_disabled.png */, + D3B9A3DE15A58C450096EA4E /* chat_send_over.png */, D31AAF61159B5B6E002C6B02 /* conference_default.png */, D31AAF62159B5B6E002C6B02 /* conference_over.png */, D354980E15875608000081D8 /* contacts_add_default.png */, @@ -1883,6 +1943,7 @@ D354980415875534000081D8 /* contacts_linphone_selected.png */, D38327FC158100E400FA0D23 /* contacts_over.png */, D38327EC1580FE3A00FA0D23 /* contacts_selected.png */, + D32B6E2B15A5C0800033019F /* database.sqlite */, D3F83F761582253100336684 /* decline_default.png */, D3F83F771582253100336684 /* decline_over.png */, D3ED3E441585FB8C006C0DE4 /* dialer_address_background.png */, @@ -2029,6 +2090,15 @@ name = Utils; sourceTree = ""; }; + D32B6E3515A5C2200033019F /* Model */ = { + isa = PBXGroup; + children = ( + D32B6E3615A5C2430033019F /* ChatModel.h */, + D32B6E3715A5C2430033019F /* ChatModel.m */, + ); + name = Model; + sourceTree = ""; + }; D37DC6C31594AE5600B2A5EB /* InAppSettingsKit */ = { isa = PBXGroup; children = ( @@ -2399,6 +2469,16 @@ D350F22C15A43D3400149E54 /* setup_welcome_logo.png in Resources */, D35406F715A47E9E007E7E81 /* button_background_default.png in Resources */, D35406F915A47E9E007E7E81 /* button_background_over.png in Resources */, + D3F795D815A582810077328B /* ChatRoomViewController.xib in Resources */, + D3F795DD15A5831C0077328B /* chat_back_default.png in Resources */, + D3F795DF15A5831C0077328B /* chat_back_over.png in Resources */, + D3B9A3DF15A58C450096EA4E /* chat_field.png in Resources */, + D3B9A3E115A58C450096EA4E /* chat_ok_default.png in Resources */, + D3B9A3E315A58C450096EA4E /* chat_ok_over.png in Resources */, + D3B9A3E515A58C450096EA4E /* chat_send_default.png in Resources */, + D3B9A3E715A58C450096EA4E /* chat_send_over.png in Resources */, + D32B6E2415A5B2020033019F /* chat_send_disabled.png in Resources */, + D32B6E2C15A5C0800033019F /* database.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2599,6 +2679,16 @@ D350F22D15A43D3400149E54 /* setup_welcome_logo.png in Resources */, D35406F815A47E9E007E7E81 /* button_background_default.png in Resources */, D35406FA15A47E9E007E7E81 /* button_background_over.png in Resources */, + D3F795D915A582810077328B /* ChatRoomViewController.xib in Resources */, + D3F795DE15A5831C0077328B /* chat_back_default.png in Resources */, + D3F795E015A5831C0077328B /* chat_back_over.png in Resources */, + D3B9A3E015A58C450096EA4E /* chat_field.png in Resources */, + D3B9A3E215A58C450096EA4E /* chat_ok_default.png in Resources */, + D3B9A3E415A58C450096EA4E /* chat_ok_over.png in Resources */, + D3B9A3E615A58C450096EA4E /* chat_send_default.png in Resources */, + D3B9A3E815A58C450096EA4E /* chat_send_over.png in Resources */, + D32B6E2515A5B2020033019F /* chat_send_disabled.png in Resources */, + D32B6E2D15A5C0800033019F /* database.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2676,6 +2766,9 @@ D32B9DFC15A2F131000B6DEC /* FastAddressBook.m in Sources */, D3196D3E15A32BD8007FEEBA /* UITransferButton.m in Sources */, D350F20E15A43BB100149E54 /* WizardViewController.m in Sources */, + D3F795D615A582810077328B /* ChatRoomViewController.m in Sources */, + D32B6E2915A5BC440033019F /* ChatRoomTableViewController.m in Sources */, + D32B6E3815A5C2430033019F /* ChatModel.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2750,6 +2843,9 @@ D32B9DFD15A2F131000B6DEC /* FastAddressBook.m in Sources */, D3196D3F15A32BD8007FEEBA /* UITransferButton.m in Sources */, D350F20F15A43BB100149E54 /* WizardViewController.m in Sources */, + D3F795D715A582810077328B /* ChatRoomViewController.m in Sources */, + D32B6E2A15A5BC440033019F /* ChatRoomTableViewController.m in Sources */, + D32B6E3915A5C2430033019F /* ChatModel.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };