forked from mirrors/linphone-iphone
435 lines
14 KiB
Objective-C
435 lines
14 KiB
Objective-C
/* DialerViewController.h
|
|
*
|
|
* Copyright (C) 2009 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 <AVFoundation/AVAudioSession.h>
|
|
#import <AudioToolbox/AudioToolbox.h>
|
|
|
|
#import "LinphoneManager.h"
|
|
#import "PhoneMainView.h"
|
|
|
|
@implementation DialerView
|
|
|
|
@synthesize transferMode;
|
|
|
|
@synthesize addressField;
|
|
@synthesize addContactButton;
|
|
@synthesize backButton;
|
|
@synthesize addCallButton;
|
|
@synthesize transferButton;
|
|
@synthesize callButton;
|
|
@synthesize backspaceButton;
|
|
|
|
@synthesize oneButton;
|
|
@synthesize twoButton;
|
|
@synthesize threeButton;
|
|
@synthesize fourButton;
|
|
@synthesize fiveButton;
|
|
@synthesize sixButton;
|
|
@synthesize sevenButton;
|
|
@synthesize eightButton;
|
|
@synthesize nineButton;
|
|
@synthesize starButton;
|
|
@synthesize zeroButton;
|
|
@synthesize hashButton;
|
|
|
|
@synthesize backgroundView;
|
|
@synthesize videoPreview;
|
|
@synthesize videoCameraSwitch;
|
|
|
|
#pragma mark - Lifecycle Functions
|
|
|
|
- (id)init {
|
|
self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]];
|
|
if (self) {
|
|
transferMode = FALSE;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
// Remove all observers
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
}
|
|
|
|
#pragma mark - UICompositeViewDelegate Functions
|
|
|
|
static UICompositeViewDescription *compositeDescription = nil;
|
|
|
|
+ (UICompositeViewDescription *)compositeViewDescription {
|
|
if (compositeDescription == nil) {
|
|
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
|
|
statusBar:StatusBarView.class
|
|
tabBar:TabBarView.class
|
|
sideMenu:SideMenuView.class
|
|
fullscreen:false
|
|
isLeftFragment:YES
|
|
fragmentWith:nil];
|
|
compositeDescription.darkBackground = true;
|
|
}
|
|
return compositeDescription;
|
|
}
|
|
|
|
- (UICompositeViewDescription *)compositeViewDescription {
|
|
return self.class.compositeViewDescription;
|
|
}
|
|
|
|
#pragma mark - ViewController Functions
|
|
|
|
- (void)viewWillAppear:(BOOL)animated {
|
|
[super viewWillAppear:animated];
|
|
|
|
// Set observer
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(callUpdateEvent:)
|
|
name:kLinphoneCallUpdate
|
|
object:nil];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(coreUpdateEvent:)
|
|
name:kLinphoneCoreUpdate
|
|
object:nil];
|
|
|
|
// technically not needed, but older versions of linphone had this button
|
|
// disabled by default. In this case, updating by pushing a new version with
|
|
// xcode would result in the callbutton being disabled all the time.
|
|
// We force it enabled anyway now.
|
|
[callButton setEnabled:TRUE];
|
|
|
|
// Update on show
|
|
LinphoneManager *mgr = [LinphoneManager instance];
|
|
LinphoneCore *lc = [LinphoneManager getLc];
|
|
LinphoneCall *call = linphone_core_get_current_call(lc);
|
|
LinphoneCallState state = (call != NULL) ? linphone_call_get_state(call) : 0;
|
|
[self callUpdate:call state:state];
|
|
|
|
if (IPAD) {
|
|
BOOL videoEnabled = linphone_core_video_display_enabled(lc);
|
|
BOOL previewPref = [mgr lpConfigBoolForKey:@"preview_preference"];
|
|
|
|
if (videoEnabled && previewPref) {
|
|
linphone_core_set_native_preview_window_id(lc, (__bridge void *)(videoPreview));
|
|
|
|
if (!linphone_core_video_preview_enabled(lc)) {
|
|
linphone_core_enable_video_preview(lc, TRUE);
|
|
}
|
|
|
|
[backgroundView setHidden:FALSE];
|
|
[videoCameraSwitch setHidden:FALSE];
|
|
} else {
|
|
linphone_core_set_native_preview_window_id(lc, NULL);
|
|
linphone_core_enable_video_preview(lc, FALSE);
|
|
[backgroundView setHidden:TRUE];
|
|
[videoCameraSwitch setHidden:TRUE];
|
|
}
|
|
}
|
|
[addressField setText:@""];
|
|
}
|
|
|
|
- (void)viewWillDisappear:(BOOL)animated {
|
|
[super viewWillDisappear:animated];
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
}
|
|
|
|
- (void)viewDidLoad {
|
|
[super viewDidLoad];
|
|
|
|
[zeroButton setDigit:'0'];
|
|
[oneButton setDigit:'1'];
|
|
[twoButton setDigit:'2'];
|
|
[threeButton setDigit:'3'];
|
|
[fourButton setDigit:'4'];
|
|
[fiveButton setDigit:'5'];
|
|
[sixButton setDigit:'6'];
|
|
[sevenButton setDigit:'7'];
|
|
[eightButton setDigit:'8'];
|
|
[nineButton setDigit:'9'];
|
|
[starButton setDigit:'*'];
|
|
[hashButton setDigit:'#'];
|
|
|
|
[addressField setAdjustsFontSizeToFitWidth:TRUE]; // Not put it in IB: issue with placeholder size
|
|
|
|
UILongPressGestureRecognizer *backspaceLongGesture =
|
|
[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onBackspaceLongClick:)];
|
|
[backspaceButton addGestureRecognizer:backspaceLongGesture];
|
|
|
|
UILongPressGestureRecognizer *zeroLongGesture =
|
|
[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onZeroLongClick:)];
|
|
[zeroButton addGestureRecognizer:zeroLongGesture];
|
|
|
|
UILongPressGestureRecognizer *oneLongGesture =
|
|
[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onOneLongClick:)];
|
|
[oneButton addGestureRecognizer:oneLongGesture];
|
|
|
|
if (IPAD) {
|
|
if ([LinphoneManager instance].frontCamId != nil) {
|
|
// only show camera switch button if we have more than 1 camera
|
|
[videoCameraSwitch setHidden:FALSE];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
|
|
duration:(NSTimeInterval)duration {
|
|
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
|
|
switch (toInterfaceOrientation) {
|
|
case UIInterfaceOrientationPortrait:
|
|
[videoPreview setTransform:CGAffineTransformMakeRotation(0)];
|
|
break;
|
|
case UIInterfaceOrientationPortraitUpsideDown:
|
|
[videoPreview setTransform:CGAffineTransformMakeRotation(M_PI)];
|
|
break;
|
|
case UIInterfaceOrientationLandscapeLeft:
|
|
[videoPreview setTransform:CGAffineTransformMakeRotation(M_PI / 2)];
|
|
break;
|
|
case UIInterfaceOrientationLandscapeRight:
|
|
[videoPreview setTransform:CGAffineTransformMakeRotation(-M_PI / 2)];
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
CGRect frame = self.view.frame;
|
|
frame.origin = CGPointMake(0, 0);
|
|
videoPreview.frame = frame;
|
|
}
|
|
|
|
#pragma mark - Event Functions
|
|
|
|
- (void)callUpdateEvent:(NSNotification *)notif {
|
|
LinphoneCall *call = [[notif.userInfo objectForKey:@"call"] pointerValue];
|
|
LinphoneCallState state = [[notif.userInfo objectForKey:@"state"] intValue];
|
|
[self callUpdate:call state:state];
|
|
}
|
|
|
|
- (void)coreUpdateEvent:(NSNotification *)notif {
|
|
if (IPAD) {
|
|
LinphoneCore *lc = [LinphoneManager getLc];
|
|
if (linphone_core_video_display_enabled(lc) && linphone_core_video_preview_enabled(lc)) {
|
|
linphone_core_set_native_preview_window_id(lc, (__bridge void *)(videoPreview));
|
|
[backgroundView setHidden:FALSE];
|
|
[videoCameraSwitch setHidden:FALSE];
|
|
} else {
|
|
linphone_core_set_native_preview_window_id(lc, NULL);
|
|
[backgroundView setHidden:TRUE];
|
|
[videoCameraSwitch setHidden:TRUE];
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma mark - Debug Functions
|
|
- (void)presentMailViewWithTitle:(NSString *)subject forRecipients:(NSArray *)recipients attachLogs:(BOOL)attachLogs {
|
|
if ([MFMailComposeViewController canSendMail]) {
|
|
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
|
|
if (controller) {
|
|
controller.mailComposeDelegate = self;
|
|
[controller setSubject:subject];
|
|
[controller setToRecipients:recipients];
|
|
|
|
if (attachLogs) {
|
|
char *filepath = linphone_core_compress_log_collection();
|
|
if (filepath == NULL) {
|
|
LOGE(@"Cannot sent logs: file is NULL");
|
|
return;
|
|
}
|
|
|
|
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
|
|
NSString *filename = [appName stringByAppendingString:@".gz"];
|
|
NSString *mimeType = @"text/plain";
|
|
|
|
if ([filename hasSuffix:@".gz"]) {
|
|
mimeType = @"application/gzip";
|
|
filename = [appName stringByAppendingString:@".gz"];
|
|
} else {
|
|
LOGE(@"Unknown extension type: %@, cancelling email", filename);
|
|
return;
|
|
}
|
|
[controller setMessageBody:NSLocalizedString(@"Application logs", nil) isHTML:NO];
|
|
[controller addAttachmentData:[NSData dataWithContentsOfFile:[NSString stringWithUTF8String:filepath]]
|
|
mimeType:mimeType
|
|
fileName:filename];
|
|
|
|
ms_free(filepath);
|
|
}
|
|
self.modalPresentationStyle = UIModalPresentationPageSheet;
|
|
[self.view.window.rootViewController presentViewController:controller
|
|
animated:TRUE
|
|
completion:^{
|
|
}];
|
|
}
|
|
|
|
} else {
|
|
UIAlertView *alert =
|
|
[[UIAlertView alloc] initWithTitle:subject
|
|
message:NSLocalizedString(@"Error: no mail account configured", nil)
|
|
delegate:nil
|
|
cancelButtonTitle:NSLocalizedString(@"OK", nil)
|
|
otherButtonTitles:nil];
|
|
[alert show];
|
|
}
|
|
}
|
|
|
|
- (BOOL)displayDebugPopup:(NSString *)address {
|
|
LinphoneManager *mgr = [LinphoneManager instance];
|
|
NSString *debugAddress = [mgr lpConfigStringForKey:@"debug_popup_magic" withDefault:@""];
|
|
if (![debugAddress isEqualToString:@""] && [address isEqualToString:debugAddress]) {
|
|
|
|
DTAlertView *alertView = [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"Debug", nil)
|
|
message:NSLocalizedString(@"Choose an action", nil)];
|
|
|
|
[alertView addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil];
|
|
|
|
[alertView
|
|
addButtonWithTitle:NSLocalizedString(@"Send logs", nil)
|
|
block:^{
|
|
NSString *appName =
|
|
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
|
|
NSString *logsAddress =
|
|
[mgr lpConfigStringForKey:@"debug_popup_email" withDefault:@"linphone-ios@linphone.org"];
|
|
[self presentMailViewWithTitle:appName forRecipients:@[ logsAddress ] attachLogs:true];
|
|
}];
|
|
|
|
BOOL debugEnabled = [[LinphoneManager instance] lpConfigBoolForKey:@"debugenable_preference"];
|
|
NSString *actionLog =
|
|
(debugEnabled ? NSLocalizedString(@"Disable logs", nil) : NSLocalizedString(@"Enable logs", nil));
|
|
[alertView addButtonWithTitle:actionLog
|
|
block:^{
|
|
// enable / disable
|
|
BOOL enableDebug = ![mgr lpConfigBoolForKey:@"debugenable_preference"];
|
|
[mgr lpConfigSetBool:enableDebug forKey:@"debugenable_preference"];
|
|
[mgr setLogsEnabled:enableDebug];
|
|
}];
|
|
|
|
[alertView show];
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (void)callUpdate:(LinphoneCall *)call state:(LinphoneCallState)state {
|
|
LinphoneCore *lc = [LinphoneManager getLc];
|
|
BOOL callInProgress = (linphone_core_get_calls_nb(lc) > 0);
|
|
addCallButton.hidden = (!callInProgress || transferMode);
|
|
transferButton.hidden = (!callInProgress || !transferMode);
|
|
addContactButton.hidden = callButton.hidden = callInProgress;
|
|
backButton.hidden = !callInProgress;
|
|
[callButton updateVideoPolicy];
|
|
}
|
|
|
|
- (void)setAddress:(NSString *)address {
|
|
[addressField setText:address];
|
|
}
|
|
|
|
- (void)setTransferMode:(BOOL)atransferMode {
|
|
transferMode = atransferMode;
|
|
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)call:(NSString *)address {
|
|
LinphoneAddress *addr = linphone_address_new(address.UTF8String);
|
|
NSString *displayName = addr ? [FastAddressBook displayNameForAddress:addr] : nil;
|
|
if (addr)
|
|
linphone_address_destroy(addr);
|
|
[self call:address displayName:displayName];
|
|
}
|
|
|
|
- (void)call:(NSString *)address displayName:(NSString *)displayName {
|
|
[[LinphoneManager instance] call:address displayName:displayName transfer:transferMode];
|
|
}
|
|
|
|
#pragma mark - UITextFieldDelegate Functions
|
|
|
|
- (BOOL)textField:(UITextField *)textField
|
|
shouldChangeCharactersInRange:(NSRange)range
|
|
replacementString:(NSString *)string {
|
|
//[textField performSelector:@selector() withObject:nil afterDelay:0];
|
|
return YES;
|
|
}
|
|
|
|
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
|
|
if (textField == addressField) {
|
|
[addressField resignFirstResponder];
|
|
}
|
|
return YES;
|
|
}
|
|
|
|
#pragma mark - MFComposeMailDelegate
|
|
|
|
- (void)mailComposeController:(MFMailComposeViewController *)controller
|
|
didFinishWithResult:(MFMailComposeResult)result
|
|
error:(NSError *)error {
|
|
[controller dismissViewControllerAnimated:TRUE
|
|
completion:^{
|
|
}];
|
|
[self.navigationController setNavigationBarHidden:TRUE animated:FALSE];
|
|
}
|
|
|
|
#pragma mark - Action Functions
|
|
|
|
- (IBAction)onAddContactClick:(id)event {
|
|
[ContactSelection setSelectionMode:ContactSelectionModeEdit];
|
|
[ContactSelection setAddAddress:[addressField text]];
|
|
[ContactSelection setSipFilter:nil];
|
|
[ContactSelection setNameOrEmailFilter:nil];
|
|
[ContactSelection enableEmailFilter:FALSE];
|
|
ContactsListView *view = VIEW(ContactsListView);
|
|
[PhoneMainView.instance changeCurrentView:view.class.compositeViewDescription push:TRUE];
|
|
}
|
|
|
|
- (IBAction)onBackClick:(id)event {
|
|
[PhoneMainView.instance changeCurrentView:CallView.compositeViewDescription];
|
|
}
|
|
|
|
- (IBAction)onAddressChange:(id)sender {
|
|
if ([self displayDebugPopup:self.addressField.text]) {
|
|
self.addressField.text = @"";
|
|
}
|
|
addContactButton.enabled = backspaceButton.enabled = addCallButton.enabled = transferButton.enabled =
|
|
([[addressField text] length] > 0);
|
|
}
|
|
|
|
- (IBAction)onBackspaceClick:(id)sender {
|
|
if ([addressField.text length] > 0) {
|
|
[addressField setText:[addressField.text substringToIndex:[addressField.text length] - 1]];
|
|
}
|
|
}
|
|
|
|
- (void)onBackspaceLongClick:(id)sender {
|
|
[addressField setText:@""];
|
|
}
|
|
|
|
- (void)onZeroLongClick:(id)sender {
|
|
// replace last character with a '+'
|
|
NSString *newAddress =
|
|
[[self.addressField.text substringToIndex:[self.addressField.text length] - 1] stringByAppendingString:@"+"];
|
|
[self.addressField setText:newAddress];
|
|
}
|
|
|
|
- (void)onOneLongClick:(id)sender {
|
|
LinphoneManager *lm = [LinphoneManager instance];
|
|
NSString *voiceMail = [lm lpConfigStringForKey:@"voice_mail_uri"];
|
|
if (voiceMail != nil) {
|
|
[lm call:voiceMail displayName:NSLocalizedString(@"Voice mail", nil) transfer:FALSE];
|
|
} else {
|
|
LOGE(@"Cannot call voice mail because URI not set!");
|
|
}
|
|
}
|
|
@end
|