From 69a1bb7feaa0e0cf67a68b81e3e40f2e4f3673ed Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 14 Aug 2012 11:09:16 +0200 Subject: [PATCH 01/12] Remove CPAnimation --- Classes/LinphoneUI/UICallBar.m | 129 +++++++---------- .../Utils/CPAnimation/CPAnimationSequence.h | 26 ---- .../Utils/CPAnimation/CPAnimationSequence.m | 84 ----------- Classes/Utils/CPAnimation/CPAnimationStep.h | 46 ------ Classes/Utils/CPAnimation/CPAnimationStep.m | 132 ------------------ linphone.xcodeproj/project.pbxproj | 24 ---- 6 files changed, 47 insertions(+), 394 deletions(-) delete mode 100755 Classes/Utils/CPAnimation/CPAnimationSequence.h delete mode 100755 Classes/Utils/CPAnimation/CPAnimationSequence.m delete mode 100755 Classes/Utils/CPAnimation/CPAnimationStep.h delete mode 100755 Classes/Utils/CPAnimation/CPAnimationStep.m diff --git a/Classes/LinphoneUI/UICallBar.m b/Classes/LinphoneUI/UICallBar.m index 07f346df1..ff13ea619 100644 --- a/Classes/LinphoneUI/UICallBar.m +++ b/Classes/LinphoneUI/UICallBar.m @@ -20,9 +20,6 @@ #import "UICallBar.h" #import "LinphoneManager.h" #import "PhoneMainView.h" - -#import "CPAnimationSequence.h" -#import "CPAnimationStep.h" #import "Utils.h" #include "linphonecore.h" @@ -281,29 +278,55 @@ } -#pragma mark - +#pragma mark - + +- (void)showAnimation:(NSString*)animationID target:(UIView*)target completion:(void (^)(BOOL finished))completion { + CGRect frame = [target frame]; + int original_y = frame.origin.y; + frame.origin.y = [[self view] frame].size.height; + [target setFrame:frame]; + [target setHidden:FALSE]; + [UIView animateWithDuration:0.5 + delay:0.0 + options:UIViewAnimationOptionCurveEaseOut + animations:^{ + CGRect frame = [target frame]; + frame.origin.y = original_y; + [target setFrame:frame]; + } + completion:^(BOOL finished){ + CGRect frame = [target frame]; + frame.origin.y = original_y; + [target setFrame:frame]; + completion(finished); + }]; +} + +- (void)hideAnimation:(NSString*)animationID target:(UIView*)target completion:(void (^)(BOOL finished))completion { + CGRect frame = [target frame]; + int original_y = frame.origin.y; + [UIView animateWithDuration:0.5 + delay:0.0 + options:UIViewAnimationOptionCurveEaseIn + animations:^{ + CGRect frame = [target frame]; + frame.origin.y = [[self view] frame].size.height; + [target setFrame:frame]; + } + completion:^(BOOL finished){ + CGRect frame = [target frame]; + frame.origin.y = original_y; + [target setHidden:TRUE]; + [target setFrame:frame]; + completion(finished); + }]; +} - (void)showPad:(BOOL)animated { [dialerButton setOn]; if([padView isHidden]) { if(animated) { - CGRect frame = [padView frame]; - int original_y = frame.origin.y; - frame.origin.y = [[self view] frame].size.height; - [padView setFrame:frame]; - [padView setHidden:FALSE]; - CPAnimationSequence* move = [[CPAnimationSequence sequenceWithSteps: - [[CPAnimationStep after:0.0 - for:0.5 - options:UIViewAnimationOptionCurveEaseOut - animate:^{ - CGRect frame = [padView frame]; - frame.origin.y = original_y; - [padView setFrame:frame]; - }] autorelease], - nil - ] autorelease]; - [move run]; + [self showAnimation:@"show" target:padView completion:^(BOOL finished){}]; } else { [padView setHidden:FALSE]; } @@ -314,28 +337,7 @@ [dialerButton setOff]; if(![padView isHidden]) { if(animated) { - CGRect frame = [padView frame]; - int original_y = frame.origin.y; - - CPAnimationSequence* move = [[CPAnimationSequence sequenceWithSteps: - [[CPAnimationStep after:0.0 - for:0.5 - options:UIViewAnimationOptionCurveEaseIn - animate:^{ - CGRect frame = [padView frame]; - frame.origin.y = [[self view] frame].size.height; - [padView setFrame:frame]; - }] autorelease], - [[CPAnimationStep after:0.0 - animate:^{ - CGRect frame = [padView frame]; - frame.origin.y = original_y; - [padView setHidden:TRUE]; - [padView setFrame:frame]; - }] autorelease], - nil - ] autorelease]; - [move run]; + [self hideAnimation:@"hide" target:padView completion:^(BOOL finished){}]; } else { [padView setHidden:TRUE]; } @@ -346,23 +348,7 @@ [optionsButton setOn]; if([optionsView isHidden]) { if(animated) { - CGRect frame = [optionsView frame]; - int original_y = frame.origin.y; - frame.origin.y = [[self view] frame].size.height; - [optionsView setFrame:frame]; - [optionsView setHidden:FALSE]; - CPAnimationSequence* move = [[CPAnimationSequence sequenceWithSteps: - [[CPAnimationStep after:0.0 - for:0.5 - options:UIViewAnimationOptionCurveEaseOut - animate:^{ - CGRect frame = [optionsView frame]; - frame.origin.y = original_y; - [optionsView setFrame:frame]; - }] autorelease], - nil - ] autorelease]; - [move run]; + [self showAnimation:@"show" target:optionsView completion:^(BOOL finished){}]; } else { [optionsView setHidden:FALSE]; } @@ -373,28 +359,7 @@ [optionsButton setOff]; if(![optionsView isHidden]) { if(animated) { - CGRect frame = [optionsView frame]; - int original_y = frame.origin.y; - - CPAnimationSequence* move = [[CPAnimationSequence sequenceWithSteps: - [[CPAnimationStep after:0.0 - for:0.5 - options:UIViewAnimationOptionCurveEaseIn - animate:^{ - CGRect frame = [optionsView frame]; - frame.origin.y = [[self view] frame].size.height; - [optionsView setFrame:frame]; - }] autorelease], - [[CPAnimationStep after:0.0 - animate:^{ - CGRect frame = [optionsView frame]; - frame.origin.y = original_y; - [optionsView setHidden:TRUE]; - [optionsView setFrame:frame]; - }] autorelease], - nil - ] autorelease]; - [move run]; + [self hideAnimation:@"hide" target:optionsView completion:^(BOOL finished){}]; } else { [optionsView setHidden:TRUE]; } diff --git a/Classes/Utils/CPAnimation/CPAnimationSequence.h b/Classes/Utils/CPAnimation/CPAnimationSequence.h deleted file mode 100755 index d018d1dfc..000000000 --- a/Classes/Utils/CPAnimation/CPAnimationSequence.h +++ /dev/null @@ -1,26 +0,0 @@ - -// Created by Yang Meyer on 26.07.11. -// Copyright 2011-2012 compeople AG. All rights reserved. - -#import -#import "CPAnimationStep.h" - -/** - A CPAnimationSequence defines a sequence of CPAnimationStep objects, which can - be `-run` animatedly or non-animatedly. - - CPAnimationSequence implements the Composite design pattern, with CPAnimationStep - as the base class. - */ -@interface CPAnimationSequence : CPAnimationStep - -#pragma mark - constructors - -+ (id) sequenceWithSteps:(CPAnimationStep*)first, ... NS_REQUIRES_NIL_TERMINATION; - -#pragma mark - properties - -/** Animations steps, from first to last. */ -@property (nonatomic, strong, readonly) NSArray* steps; - -@end diff --git a/Classes/Utils/CPAnimation/CPAnimationSequence.m b/Classes/Utils/CPAnimation/CPAnimationSequence.m deleted file mode 100755 index d0b1ebd35..000000000 --- a/Classes/Utils/CPAnimation/CPAnimationSequence.m +++ /dev/null @@ -1,84 +0,0 @@ - -// Created by Yang Meyer on 26.07.11. -// Copyright 2011-2012 compeople AG. All rights reserved. - -#import "CPAnimationSequence.h" - -@interface CPAnimationStep(hidden) -- (NSArray*) animationStepArray; -@end - -@interface CPAnimationSequence() -@property (nonatomic, strong, readwrite) NSArray* steps; -@end - -#pragma mark - -@implementation CPAnimationSequence - -@synthesize steps; - -#pragma mark - Object lifecycle - -+ (id) sequenceWithSteps:(CPAnimationStep*)first, ... { - CPAnimationSequence* instance = [[self alloc] init]; - if (instance) { - NSMutableArray* tempSteps = [[NSMutableArray alloc] initWithCapacity:10]; - va_list args; - va_start(args, first); - [tempSteps insertObject:first atIndex:0]; - CPAnimationStep* aStep; - while ((aStep = va_arg(args, CPAnimationStep*))) { - [tempSteps insertObject:aStep atIndex:0]; - } - instance.steps = [NSArray arrayWithArray:tempSteps]; - va_end(args); - [tempSteps release]; - } - return instance; -} - -- (void) dealloc { - [steps release]; - [super dealloc]; -} - -#pragma mark - property override - -- (void) setDelay:(NSTimeInterval)delay { - NSAssert(NO, @"Setting a delay on a sequence is undefined and therefore disallowed!"); -} - -- (void) setDuration:(NSTimeInterval)duration { - NSAssert(NO, @"Setting a duration on a sequence is undefined and therefore disallowed!"); -} - -- (void) setOptions:(UIViewAnimationOptions)options { - NSAssert(NO, @"Setting options on a sequence is undefined and therefore disallowed!"); -} - -#pragma mark - build the sequence - -- (NSArray*) animationStepArray { - NSMutableArray* array = [NSMutableArray arrayWithCapacity:[self.steps count]]; - for (CPAnimationStep* current in self.steps) { - [array addObjectsFromArray:[current animationStepArray]]; - } - return array; -} - -#pragma mark - pretty-print - -- (NSString*) description { - NSMutableString* sequenceBody = [[NSMutableString alloc] initWithCapacity:100*[self.steps count]]; - for (CPAnimationStep* step in self.steps) { - [sequenceBody appendString:[step description]]; - } - // indent - [sequenceBody replaceOccurrencesOfString:@"\n" - withString:@"\n " - options:NSCaseInsensitiveSearch - range:NSMakeRange(0, [sequenceBody length])]; - return [NSString stringWithFormat:@"\n(sequence:%@\n)", sequenceBody]; -} - -@end diff --git a/Classes/Utils/CPAnimation/CPAnimationStep.h b/Classes/Utils/CPAnimation/CPAnimationStep.h deleted file mode 100755 index 709594a7c..000000000 --- a/Classes/Utils/CPAnimation/CPAnimationStep.h +++ /dev/null @@ -1,46 +0,0 @@ - -// Created by Yang Meyer on 26.07.11. -// Copyright 2011 compeople AG. All rights reserved. - -#import - -/** Helper type definition for the component. */ -typedef void (^AnimationStep)(void); - -/** - A CPAnimationStep defines a single animation object with a delay, duration, execution block and animation options. - */ -@interface CPAnimationStep : NSObject - -#pragma mark - constructors - -+ (id) after:(NSTimeInterval)delay - animate:(AnimationStep)step; - -+ (id) for:(NSTimeInterval)duration - animate:(AnimationStep)step; - -+ (id) after:(NSTimeInterval)delay - for:(NSTimeInterval)duration - animate:(AnimationStep)step; - -+ (id) after:(NSTimeInterval)delay - for:(NSTimeInterval)duration - options:(UIViewAnimationOptions)theOptions - animate:(AnimationStep)step; - -#pragma mark - properties (normally already set by the constructor) - -@property (nonatomic) NSTimeInterval delay; -@property (nonatomic) NSTimeInterval duration; -@property (nonatomic, strong) AnimationStep step; -@property (nonatomic) UIViewAnimationOptions options; - -#pragma mark - execution - -/** Starts the step execution. */ -- (void) runAnimated:(BOOL)animated; -/** Shortcut for [step runAnimated:YES] */ -- (void) run; - -@end diff --git a/Classes/Utils/CPAnimation/CPAnimationStep.m b/Classes/Utils/CPAnimation/CPAnimationStep.m deleted file mode 100755 index 4ad40220f..000000000 --- a/Classes/Utils/CPAnimation/CPAnimationStep.m +++ /dev/null @@ -1,132 +0,0 @@ - -// Created by Yang Meyer on 26.07.11. -// Copyright 2011-2012 compeople AG. All rights reserved. - -#import "CPAnimationStep.h" - -@interface CPAnimationStep() -/** A temporary reverse queue of animation steps, i.e. from last to first. - It is created when the step is run, and is modified during the animation, - and is destroyed when the animation finishes. */ -@property (nonatomic, strong) NSMutableArray* consumableSteps; -@end - -@implementation CPAnimationStep - -@synthesize delay, duration, step, options; -@synthesize consumableSteps; - -#pragma mark overrides - - -#pragma mark construction - -+ (id) after:(NSTimeInterval)delay animate:(AnimationStep)step { - return [self after:delay for:0.0 options:0 animate:step]; -} - -+ (id) for:(NSTimeInterval)duration animate:(AnimationStep)step { - return [self after:0.0 for:duration options:0 animate:step]; -} - -+ (id) after:(NSTimeInterval)delay for:(NSTimeInterval)duration animate:(AnimationStep)step { - return [self after:delay for:duration options:0 animate:step]; -} - -+ (id) after:(NSTimeInterval)theDelay - for:(NSTimeInterval)theDuration - options:(UIViewAnimationOptions)theOptions - animate:(AnimationStep)theStep { - - CPAnimationStep* instance = [[self alloc] init]; - if (instance) { - instance.delay = theDelay; - instance.duration = theDuration; - instance.options = theOptions; - instance.step = theStep; - } - return instance; -} - -- (void)dealloc { - [step release]; - [super dealloc]; -} - -#pragma mark action - -// From http://stackoverflow.com/questions/4007023/blocks-instead-of-performselectorwithobjectafterdelay -+ (void) runBlock:(AnimationStep)block afterDelay:(NSTimeInterval)delay { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay), dispatch_get_current_queue(), block); -} - -- (NSArray*) animationStepArray { - // subclasses must override this! - return [NSArray arrayWithObject:self]; -} - -- (void) runAnimated:(BOOL)animated { - if (!self.consumableSteps) { - self.consumableSteps = [[NSMutableArray alloc] initWithArray:[self animationStepArray]]; - } - if (![self.consumableSteps count]) { // recursion anchor - [self.consumableSteps release]; - self.consumableSteps = nil; - return; // we're done - } - void (^completionStep)(BOOL) = ^(BOOL animated){ - [self.consumableSteps removeLastObject]; - [self runAnimated:animated]; // recurse! - }; - CPAnimationStep* currentStep = [self.consumableSteps lastObject]; - // Note: do not animate to short steps - if (animated && currentStep.duration >= 0.02) { - [UIView animateWithDuration:currentStep.duration - delay:currentStep.delay - options:currentStep.options - animations:currentStep.step - completion:^(BOOL finished) { - if (finished) { - completionStep(TRUE); - } else { - completionStep(FALSE); - } - }]; - } else { - void (^execution)(void) = ^{ - currentStep.step(); - completionStep(FALSE); - }; - - if (animated && currentStep.delay) { - [CPAnimationStep runBlock:execution afterDelay:currentStep.delay]; - } else { - execution(); - } - } -} - -- (void) run { - [self runAnimated:YES]; -} - -#pragma mark - pretty-print - -- (NSString*) description { - NSMutableString* result = [[NSMutableString alloc] initWithCapacity:100]; - [result appendString:@"\n["]; - if (self.delay > 0.0) { - [result appendFormat:@"after:%.1f ", self.delay]; - } - if (self.duration > 0.0) { - [result appendFormat:@"for:%.1f ", self.duration]; - } - if (self.options > 0) { - [result appendFormat:@"options:%d ", self.options]; - } - [result appendFormat:@"animate:%@", self.step]; - [result appendString:@"]"]; - return result; -} - -@end diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 9d563572d..d809609ee 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -743,10 +743,6 @@ D3832801158100E400FA0D23 /* history_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327FD158100E400FA0D23 /* history_over.png */; }; D3832802158100E400FA0D23 /* settings_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327FE158100E400FA0D23 /* settings_over.png */; }; D3832803158100E400FA0D23 /* chat_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327FF158100E400FA0D23 /* chat_over.png */; }; - D389362615A6D19800A3A3AA /* CPAnimationSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D389362315A6D19800A3A3AA /* CPAnimationSequence.m */; }; - D389362715A6D19800A3A3AA /* CPAnimationSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D389362315A6D19800A3A3AA /* CPAnimationSequence.m */; }; - D389362815A6D19800A3A3AA /* CPAnimationStep.m in Sources */ = {isa = PBXBuildFile; fileRef = D389362515A6D19800A3A3AA /* CPAnimationStep.m */; }; - D389362915A6D19800A3A3AA /* CPAnimationStep.m in Sources */ = {isa = PBXBuildFile; fileRef = D389362515A6D19800A3A3AA /* CPAnimationStep.m */; }; D389363915A6D53200A3A3AA /* chat_bubble_incoming.9.png in Resources */ = {isa = PBXBuildFile; fileRef = D389363715A6D53200A3A3AA /* chat_bubble_incoming.9.png */; }; D389363B15A6D53200A3A3AA /* chat_bubble_outgoing.9.png in Resources */ = {isa = PBXBuildFile; fileRef = D389363815A6D53200A3A3AA /* chat_bubble_outgoing.9.png */; }; D38D14AF15A30B3D008497E8 /* cell_call_first_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = D38D14AD15A30B3D008497E8 /* cell_call_first_highlight.png */; }; @@ -1744,10 +1740,6 @@ D38327FD158100E400FA0D23 /* history_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_over.png; path = Resources/history_over.png; sourceTree = ""; }; D38327FE158100E400FA0D23 /* settings_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = settings_over.png; path = Resources/settings_over.png; sourceTree = ""; }; D38327FF158100E400FA0D23 /* chat_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_over.png; path = Resources/chat_over.png; sourceTree = ""; }; - D389362215A6D19800A3A3AA /* CPAnimationSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CPAnimationSequence.h; path = Utils/CPAnimation/CPAnimationSequence.h; sourceTree = ""; }; - D389362315A6D19800A3A3AA /* CPAnimationSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CPAnimationSequence.m; path = Utils/CPAnimation/CPAnimationSequence.m; sourceTree = ""; }; - D389362415A6D19800A3A3AA /* CPAnimationStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CPAnimationStep.h; path = Utils/CPAnimation/CPAnimationStep.h; sourceTree = ""; }; - D389362515A6D19800A3A3AA /* CPAnimationStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CPAnimationStep.m; path = Utils/CPAnimation/CPAnimationStep.m; sourceTree = ""; }; D389363715A6D53200A3A3AA /* chat_bubble_incoming.9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_bubble_incoming.9.png; path = Resources/chat_bubble_incoming.9.png; sourceTree = ""; }; D389363815A6D53200A3A3AA /* chat_bubble_outgoing.9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_bubble_outgoing.9.png; path = Resources/chat_bubble_outgoing.9.png; sourceTree = ""; }; D38D14AD15A30B3D008497E8 /* cell_call_first_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cell_call_first_highlight.png; path = Resources/cell_call_first_highlight.png; sourceTree = ""; }; @@ -3074,7 +3066,6 @@ children = ( D380801215C299D0005BE9BC /* ColorSpaceUtilites.m */, D380801115C29984005BE9BC /* ColorSpaceUtilities.h */, - D38935F715A6D06800A3A3AA /* CPAnimation */, D3807FB615C28940005BE9BC /* DCRoundSwitch */, D32B9DFA15A2F131000B6DEC /* FastAddressBook.h */, D32B9DFB15A2F131000B6DEC /* FastAddressBook.m */, @@ -3185,17 +3176,6 @@ path = Views; sourceTree = ""; }; - D38935F715A6D06800A3A3AA /* CPAnimation */ = { - isa = PBXGroup; - children = ( - D389362215A6D19800A3A3AA /* CPAnimationSequence.h */, - D389362315A6D19800A3A3AA /* CPAnimationSequence.m */, - D389362415A6D19800A3A3AA /* CPAnimationStep.h */, - D389362515A6D19800A3A3AA /* CPAnimationStep.m */, - ); - name = CPAnimation; - sourceTree = ""; - }; D398D3031594B0FB00FD553C /* Settings */ = { isa = PBXGroup; children = ( @@ -4302,8 +4282,6 @@ D32B6E2915A5BC440033019F /* ChatRoomTableViewController.m in Sources */, D32B6E3815A5C2430033019F /* ChatModel.m in Sources */, D3A8BB7015A6C7D500F96BE5 /* UIChatRoomCell.m in Sources */, - D389362615A6D19800A3A3AA /* CPAnimationSequence.m in Sources */, - D389362815A6D19800A3A3AA /* CPAnimationStep.m in Sources */, D3128FE115AABC7E00A2147A /* ContactDetailsViewController.m in Sources */, D37C639515AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */, D37C639B15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */, @@ -4393,8 +4371,6 @@ D32B6E2A15A5BC440033019F /* ChatRoomTableViewController.m in Sources */, D32B6E3915A5C2430033019F /* ChatModel.m in Sources */, D3A8BB7115A6C7D500F96BE5 /* UIChatRoomCell.m in Sources */, - D389362715A6D19800A3A3AA /* CPAnimationSequence.m in Sources */, - D389362915A6D19800A3A3AA /* CPAnimationStep.m in Sources */, D3128FE215AABC7E00A2147A /* ContactDetailsViewController.m in Sources */, D37C639615AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */, D37C639C15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */, From 46569ae156f589bc41fb938a59e6b906f28a50fa Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 14 Aug 2012 11:24:32 +0200 Subject: [PATCH 02/12] Simplify Wizard inner functions --- Classes/WizardViewController.m | 58 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/Classes/WizardViewController.m b/Classes/WizardViewController.m index 746bae50a..35d50eae7 100644 --- a/Classes/WizardViewController.m +++ b/Classes/WizardViewController.m @@ -178,12 +178,12 @@ static UICompositeViewDescription *compositeDescription = nil; [waitView setHidden:TRUE]; } -+ (UIView*)findTextField:(ViewElement)tag view:(UIView*)view { ++ (UIView*)findView:(ViewElement)tag view:(UIView*)view { for(UIView *child in [view subviews]) { if([child tag] == tag){ return (UITextField*)child; } else { - UIView *o = [WizardViewController findTextField:tag view:child]; + UIView *o = [WizardViewController findView:tag view:child]; if(o) return o; } @@ -191,17 +191,17 @@ static UICompositeViewDescription *compositeDescription = nil; return nil; } -- (UITextField*)findTextField:(ViewElement)tag { - UIView *view = [WizardViewController findTextField:tag view:contentView]; - if([view isKindOfClass:[UITextField class]]) - return (UITextField*)view; ++ (UITextField*)findTextField:(ViewElement)tag view:(UIView*)view { + UIView *aview = [WizardViewController findView:tag view:view]; + if([aview isKindOfClass:[UITextField class]]) + return (UITextField*)aview; return nil; } -- (UILabel*)findLabel:(ViewElement)tag { - UIView *view = [WizardViewController findTextField:tag view:contentView]; - if([view isKindOfClass:[UILabel class]]) - return (UILabel*)view; ++ (UILabel*)findLabel:(ViewElement)tag view:(UIView*)view { + UIView *aview = [WizardViewController findView:tag view:view]; + if([aview isKindOfClass:[UILabel class]]) + return (UILabel*)aview; return nil; } @@ -379,30 +379,30 @@ static UICompositeViewDescription *compositeDescription = nil; } - (IBAction)onCheckValidationClick:(id)sender { - NSString *username = [self findTextField:ViewElement_Username].text; + NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; [self checkAccountValidation:[NSString stringWithFormat:@"%@@%@", username, LINPHONE_WIZARD_DOMAIN]]; } - (IBAction)onSignInExternalClick:(id)sender { [self.waitView setHidden:false]; - NSString *username = [self findTextField:ViewElement_Username].text; - NSString *password = [self findTextField:ViewElement_Password].text; - NSString *domain = [self findTextField:ViewElement_Domain].text; + NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; + NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; + NSString *domain = [WizardViewController findTextField:ViewElement_Domain view:contentView].text; [self addProxyConfig:username password:password domain:domain]; } - (IBAction)onSignInClick:(id)sender { [self.waitView setHidden:false]; - NSString *username = [self findTextField:ViewElement_Username].text; - NSString *password = [self findTextField:ViewElement_Password].text; + NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; + NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; [self addProxyConfig:username password:password domain:LINPHONE_WIZARD_DOMAIN]; } - (IBAction)onRegisterClick:(id)sender { - NSString *username = [self findTextField:ViewElement_Username].text; - NSString *password = [self findTextField:ViewElement_Password].text; - NSString *password2 = [self findTextField:ViewElement_Password2].text; - NSString *email = [self findTextField:ViewElement_Email].text; + NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; + NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; + NSString *password2 = [WizardViewController findTextField:ViewElement_Password2 view:contentView].text; + NSString *email = [WizardViewController findTextField:ViewElement_Email view:contentView].text; NSMutableString *errors = [NSMutableString string]; if ([username length] < LINPHONE_WIZARD_MIN_USERNAME_LENGTH) { @@ -526,18 +526,18 @@ static UICompositeViewDescription *compositeDescription = nil; [errorView show]; [errorView release]; } else { - NSString *username = [self findTextField:ViewElement_Username].text; - NSString *password = [self findTextField:ViewElement_Password].text; - NSString *email = [self findTextField:ViewElement_Email].text; + NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; + NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; + NSString *email = [WizardViewController findTextField:ViewElement_Email view:contentView].text; [self createAccount:[NSString stringWithFormat:@"%@@%@", username, LINPHONE_WIZARD_DOMAIN] password:password email:email]; } } else if([[request method] isEqualToString:@"create_account_with_useragent"]) { if([response object] == [NSNumber numberWithInt:0]) { - NSString *username = [self findTextField:ViewElement_Username].text; - NSString *password = [self findTextField:ViewElement_Password].text; + NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; + NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; [self changeView:validateAccountView back:FALSE animation:TRUE]; - [self findTextField:ViewElement_Username].text = username; - [self findTextField:ViewElement_Password].text = password; + [WizardViewController findTextField:ViewElement_Username view:contentView].text = username; + [WizardViewController findTextField:ViewElement_Password view:contentView].text = password; } else { UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Account creation issue",nil) message:NSLocalizedString(@"Can't create the account. Please try again.", nil) @@ -549,8 +549,8 @@ static UICompositeViewDescription *compositeDescription = nil; } } else if([[request method] isEqualToString:@"check_account_validated"]) { if([response object] == [NSNumber numberWithInt:1]) { - NSString *username = [self findTextField:ViewElement_Username].text; - NSString *password = [self findTextField:ViewElement_Password].text; + NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; + NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; [self addProxyConfig:username password:password domain:LINPHONE_WIZARD_DOMAIN]; } else { UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Account validation issue",nil) From de1ecec3a5fd094720a20d16a299cb774493a697 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 14 Aug 2012 13:04:40 +0200 Subject: [PATCH 03/12] Fix Wizard messagebox when communication/http error --- Classes/WizardViewController.m | 12 ++++++------ Classes/WizardViewController.xib | 2 +- Resources/en.lproj/Localizable.strings | Bin 13432 -> 13344 bytes 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Classes/WizardViewController.m b/Classes/WizardViewController.m index 35d50eae7..d14f08d26 100644 --- a/Classes/WizardViewController.m +++ b/Classes/WizardViewController.m @@ -503,7 +503,7 @@ static UICompositeViewDescription *compositeDescription = nil; #pragma mark - XMLRPCConnectionDelegate Functions -- (void)request: (XMLRPCRequest *)request didReceiveResponse: (XMLRPCResponse *)response { +- (void)request:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response { [LinphoneLogger log:LinphoneLoggerDebug format:@"XMLRPC %@: %@", [request method], [response body]]; [waitView setHidden:true]; if ([response isFault]) { @@ -515,7 +515,7 @@ static UICompositeViewDescription *compositeDescription = nil; otherButtonTitles:nil,nil]; [errorView show]; [errorView release]; - } else { + } else if([response object] != nil) { //Don't handle if not object: HTTP/Communication Error if([[request method] isEqualToString:@"check_account"]) { if([response object] == [NSNumber numberWithInt:1]) { UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Check issue",nil) @@ -565,7 +565,7 @@ static UICompositeViewDescription *compositeDescription = nil; } } -- (void)request: (XMLRPCRequest *)request didFailWithError: (NSError *)error { +- (void)request:(XMLRPCRequest *)request didFailWithError:(NSError *)error { NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Can't create account: Communication issue (%@)", nil), [error localizedDescription]]; UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Communication issue", nil) message:errorString @@ -577,15 +577,15 @@ static UICompositeViewDescription *compositeDescription = nil; [waitView setHidden:true]; } -- (BOOL)request: (XMLRPCRequest *)request canAuthenticateAgainstProtectionSpace: (NSURLProtectionSpace *)protectionSpace { +- (BOOL)request:(XMLRPCRequest *)request canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { return FALSE; } -- (void)request: (XMLRPCRequest *)request didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge { +- (void)request:(XMLRPCRequest *)request didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { } -- (void)request: (XMLRPCRequest *)request didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge { +- (void)request:(XMLRPCRequest *)request didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { } diff --git a/Classes/WizardViewController.xib b/Classes/WizardViewController.xib index 9d175e6d6..90049c4fa 100644 --- a/Classes/WizardViewController.xib +++ b/Classes/WizardViewController.xib @@ -401,7 +401,7 @@ 200 NO IBCocoaTouchFramework - Enter you username and password with your SIP domain + Enter you username and password with your email address 0 diff --git a/Resources/en.lproj/Localizable.strings b/Resources/en.lproj/Localizable.strings index 0f3dedb8c13983782fa3e30ad067350153a4a6be..58075abdac672175be6d344f3d8dd806ffb5d752 100644 GIT binary patch delta 28 icmey7u^?lE3HRhJ{3?@Qaq~=`z|93>Z+^wyrvU)5+6#67 delta 44 ncmZ3G@grk{3HRi0+!B+;c=(vD7!)QOa@(TujW^HZZqfh%Mga{3 From 919e732dc0f84ccac892589d4ed75e683412ad3a Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 14 Aug 2012 14:44:29 +0200 Subject: [PATCH 04/12] Fix Wizard messagebox --- Classes/WizardViewController.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/WizardViewController.m b/Classes/WizardViewController.m index d14f08d26..04711c118 100644 --- a/Classes/WizardViewController.m +++ b/Classes/WizardViewController.m @@ -507,7 +507,7 @@ static UICompositeViewDescription *compositeDescription = nil; [LinphoneLogger log:LinphoneLoggerDebug format:@"XMLRPC %@: %@", [request method], [response body]]; [waitView setHidden:true]; if ([response isFault]) { - NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Can't create account: Communication issue (%@)", nil), [response faultString]]; + NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Communication issue (%@)", nil), [response faultString]]; UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Communication issue",nil) message:errorString delegate:nil @@ -566,7 +566,7 @@ static UICompositeViewDescription *compositeDescription = nil; } - (void)request:(XMLRPCRequest *)request didFailWithError:(NSError *)error { - NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Can't create account: Communication issue (%@)", nil), [error localizedDescription]]; + NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Communication issue (%@)", nil), [error localizedDescription]]; UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Communication issue", nil) message:errorString delegate:nil From efa6a69780591608e73309d8ce1212085f814f79 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 14 Aug 2012 15:00:02 +0200 Subject: [PATCH 05/12] Add sip URL support --- Classes/LinphoneAppDelegate.m | 12 ++++++++++++ linphone-Info.plist | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index cd7f89a06..8cdbcd2d8 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -184,6 +184,18 @@ int __aeabi_idiv(int a, int b) { - (void)applicationWillTerminate:(UIApplication *)application { } +- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { + [self startApplication]; + if([LinphoneManager isLcReady]) { + // Go to ChatRoom view + DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription] push:TRUE], DialerViewController); + if(controller != nil) { + [controller setAddress:[url absoluteString]]; + } + } + return YES; +} + - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { [LinphoneLogger log:LinphoneLoggerDebug format:@"PushNotification: Receive %@", userInfo]; NSDictionary *aps = [userInfo objectForKey:@"aps"]; diff --git a/linphone-Info.plist b/linphone-Info.plist index 22181516a..7b5fcad31 100644 --- a/linphone-Info.plist +++ b/linphone-Info.plist @@ -2,6 +2,17 @@ + CFBundleURLTypes + + + CFBundleURLName + org.linphone.phone + CFBundleURLSchemes + + sip + + + CFBundleDevelopmentRegion English CFBundleDisplayName From 0ff2d2ec84829d5514564c670ecb160d7dacb916 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 14 Aug 2012 15:08:01 +0200 Subject: [PATCH 06/12] Add filter to URL open support --- Classes/LinphoneAppDelegate.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 8cdbcd2d8..29fd31a43 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -187,10 +187,12 @@ int __aeabi_idiv(int a, int b) { - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { [self startApplication]; if([LinphoneManager isLcReady]) { - // Go to ChatRoom view - DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription] push:TRUE], DialerViewController); - if(controller != nil) { - [controller setAddress:[url absoluteString]]; + if([[url scheme] isEqualToString:@"sip"]) { + // Go to ChatRoom view + DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription] push:TRUE], DialerViewController); + if(controller != nil) { + [controller setAddress:[url absoluteString]]; + } } } return YES; From 8d5379bc0bf7f77b3b8ef02c74945814346c8fce Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 14 Aug 2012 15:13:21 +0200 Subject: [PATCH 07/12] Fix view change on SIP url opening --- Classes/LinphoneAppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 29fd31a43..47856aefc 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -189,7 +189,7 @@ int __aeabi_idiv(int a, int b) { if([LinphoneManager isLcReady]) { if([[url scheme] isEqualToString:@"sip"]) { // Go to ChatRoom view - DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription] push:TRUE], DialerViewController); + DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); if(controller != nil) { [controller setAddress:[url absoluteString]]; } From a07155a930b12c1ed23a21919f77da0327ee5a01 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 14 Aug 2012 16:32:46 +0200 Subject: [PATCH 08/12] Fix localization --- Classes/LinphoneCoreSettingsStore.m | 3 ++- Resources/en.lproj/Localizable.strings | Bin 13344 -> 13344 bytes 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index c20b36a8f..acc6e1f55 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -362,7 +362,8 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); for(int i = 0; i < [tokenData length]; ++i) { [tokenString appendFormat:@"%02X", (unsigned int)tokenBuffer[i]]; } - // NSLocalizedString(@"IC_MSG", nil); // Fake + // NSLocalizedString(@"IC_MSG", nil); // Fake for genstrings + // NSLocalizedString(@"IM_MSG", nil); // Fake for genstrings NSString *params = [NSString stringWithFormat:@"APN-TOK=%@;APN-MSG=IM_MSG;APN-CAL=IC_MSG;APN-CAL-SND=ring.caf;APN-MSG-SND=msg.caf", tokenString]; linphone_proxy_config_set_contact_parameters(proxyCfg, [params UTF8String]); } diff --git a/Resources/en.lproj/Localizable.strings b/Resources/en.lproj/Localizable.strings index 58075abdac672175be6d344f3d8dd806ffb5d752..91e033ae9682c01b725ca7d25905f1628393d07a 100644 GIT binary patch delta 50 zcmV-20L}lPXrO2U{{NG)15vS3;tI3&3l;>EUJoLZSPPz$j1Ug97!cwXlaMEXlk6sz Ivk)i`3^9ciHUIzs delta 56 zcmV-80LTBJXrO2U|NfH!15mM3;tG?S4kVLp51z9%3l;>Ej}Q#A84%(YlZhvYlkFys OlSe2fvo|Q|3jqL$!4*LO From a506e6b2a15a7ced63f03a4aed42fe5e6c418140 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 14 Aug 2012 17:58:38 +0200 Subject: [PATCH 09/12] Use same call/message incoming message --- Classes/PhoneMainView.m | 4 ++-- Resources/en.lproj/Localizable.strings | Bin 13344 -> 12992 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index 657ac740a..d86226176 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -587,7 +587,7 @@ static PhoneMainView* phoneMainViewInstance=nil; UILocalNotification* notif = [[[UILocalNotification alloc] init] autorelease]; if (notif) { notif.repeatInterval = 0; - notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"%@ sent you a message",nil), address]; + notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG",nil), address]; notif.alertAction = NSLocalizedString(@"Show", nil); notif.soundName = @"msg.caf"; notif.userInfo = [NSDictionary dictionaryWithObject:[chat remoteContact] forKey:@"chat"]; @@ -638,7 +638,7 @@ static PhoneMainView* phoneMainViewInstance=nil; appData->notification = [[UILocalNotification alloc] init]; if (appData->notification) { appData->notification.repeatInterval = 0; - appData->notification.alertBody =[NSString stringWithFormat:NSLocalizedString(@" %@ is calling you",nil), address]; + appData->notification.alertBody =[NSString stringWithFormat:NSLocalizedString(@"IC_MSG",nil), address]; appData->notification.alertAction = NSLocalizedString(@"Answer", nil); appData->notification.soundName = @"ring.caf"; appData->notification.userInfo = [NSDictionary dictionaryWithObject:[NSData dataWithBytes:&call length:sizeof(call)] forKey:@"call"]; diff --git a/Resources/en.lproj/Localizable.strings b/Resources/en.lproj/Localizable.strings index 91e033ae9682c01b725ca7d25905f1628393d07a..78ad42e2428add4689948467a112c894b92dbfc4 100644 GIT binary patch delta 15 XcmZ3GaUgX<=*IsG7&nJ9pEdvhKvoB8 delta 191 zcmX?*x*%ghsJ|+M1A_uXCPOihOlC-A$N|DkhCGIJAit6!pP`gN3COYqVh~MG_2dUU zksE^-F@`GuO-u!vQvx?f0cg4cLoQIX7zh)AHl!k%4KbOZp2-*ZqBnnJJZ}I19YiLy From c786f60d818dd9533530b2a01bc49b0e12f2e1dc Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 14 Aug 2012 23:47:51 +0200 Subject: [PATCH 10/12] repair background mode and fix double instanciation of settingsStore, causing inconsistencies between visible configuration and used one. rename RFC dtmf. --- Classes/LinphoneAppDelegate.m | 53 ++++++++++++++---------- Classes/LinphoneCoreSettingsStore.m | 2 +- Classes/LinphoneManager.h | 1 + Classes/LinphoneManager.m | 13 +++--- Settings/InAppSettings.bundle/Call.plist | 4 +- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 47856aefc..5465b209f 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -82,22 +82,30 @@ int __aeabi_idiv(int a, int b) { } } +- (void)applicationDidEnterBackground:(UIApplication *)application{ + [LinphoneLogger logc:LinphoneLoggerLog format:"applicationDidEnterBackground"]; + if(![LinphoneManager isLcReady]) return; + [[LinphoneManager instance] enterBackgroundMode]; +} + - (void)applicationWillResignActive:(UIApplication *)application { + [LinphoneLogger logc:LinphoneLoggerLog format:"applicationWillResignActive"]; if(![LinphoneManager isLcReady]) return; LinphoneCore* lc = [LinphoneManager getLc]; LinphoneCall* call = linphone_core_get_current_call(lc); - if (call == NULL) - return; + + + if (call){ + /* save call context */ + LinphoneManager* instance = [LinphoneManager instance]; + instance->currentCallContextBeforeGoingBackground.call = call; + instance->currentCallContextBeforeGoingBackground.cameraIsEnabled = linphone_call_camera_enabled(call); - /* save call context */ - LinphoneManager* instance = [LinphoneManager instance]; - instance->currentCallContextBeforeGoingBackground.call = call; - instance->currentCallContextBeforeGoingBackground.cameraIsEnabled = linphone_call_camera_enabled(call); - - const LinphoneCallParams* params = linphone_call_get_current_params(call); - if (linphone_call_params_video_enabled(params)) { - linphone_call_enable_camera(call, false); - } + const LinphoneCallParams* params = linphone_call_get_current_params(call); + if (linphone_call_params_video_enabled(params)) { + linphone_call_enable_camera(call, false); + } + } if (![[LinphoneManager instance] resignActive]) { // destroying eventHandler if app cannot go in background. @@ -111,7 +119,8 @@ int __aeabi_idiv(int a, int b) { } -- (void)applicationDidBecomeActive:(UIApplication *)application { +- (void)applicationDidBecomeActive:(UIApplication *)application { + [LinphoneLogger logc:LinphoneLoggerLog format:"applicationDidBecomeActive"]; [self startApplication]; [[LinphoneManager instance] becomeActive]; @@ -121,19 +130,19 @@ int __aeabi_idiv(int a, int b) { LinphoneCore* lc = [LinphoneManager getLc]; LinphoneCall* call = linphone_core_get_current_call(lc); - if (call == NULL) - return; - LinphoneManager* instance = [LinphoneManager instance]; - if (call == instance->currentCallContextBeforeGoingBackground.call) { - const LinphoneCallParams* params = linphone_call_get_current_params(call); - if (linphone_call_params_video_enabled(params)) { - linphone_call_enable_camera( + if (call){ + LinphoneManager* instance = [LinphoneManager instance]; + if (call == instance->currentCallContextBeforeGoingBackground.call) { + const LinphoneCallParams* params = linphone_call_get_current_params(call); + if (linphone_call_params_video_enabled(params)) { + linphone_call_enable_camera( call, instance->currentCallContextBeforeGoingBackground.cameraIsEnabled); - } - instance->currentCallContextBeforeGoingBackground.call = 0; - } + } + instance->currentCallContextBeforeGoingBackground.call = 0; + } + } } - (void)setupGSMInteraction { diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index acc6e1f55..86bd9814a 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -377,9 +377,9 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); } - (BOOL)synchronize { + if (![LinphoneManager isLcReady]) return YES; LinphoneCore *lc=[LinphoneManager getLc]; - if (lc==NULL) return YES; BOOL account_changed; account_changed=[self valueChangedForKey:@"username_preference"] diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index d1e847b60..34bcabc3c 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -107,6 +107,7 @@ typedef struct _LinphoneManagerSounds { - (void)destroyLibLinphone; - (BOOL)resignActive; - (void)becomeActive; +- (BOOL)enterBackgroundMode; + (void)kickOffNetworkConnection; - (void)setupNetworkReachabilityCallback; diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index eb7884f15..e1fc78eb5 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -668,7 +668,8 @@ static LinphoneCoreVTable linphonec_vtable = { else ms_set_cpu_count(1); - settingsStore = [[LinphoneCoreSettingsStore alloc] init]; + if (!settingsStore) + settingsStore = [[LinphoneCoreSettingsStore alloc] init]; [LinphoneLogger logc:LinphoneLoggerWarning format:"Linphone [%s] started on [%s]" ,linphone_core_get_version() @@ -686,10 +687,12 @@ static LinphoneCoreVTable linphonec_vtable = { [mIterateTimer invalidate]; AVAudioSession *audioSession = [AVAudioSession sharedInstance]; [audioSession setDelegate:nil]; +#if 0 if (settingsStore != nil) { [settingsStore release]; settingsStore = nil; } +#endif if (theLinphoneCore != nil) { //just in case application terminate before linphone core initialization [LinphoneLogger logc:LinphoneLoggerLog format:"Destroy linphonecore"]; linphone_core_destroy(theLinphoneCore); @@ -705,19 +708,19 @@ static LinphoneCoreVTable linphonec_vtable = { - (BOOL)resignActive { if ([[LinphoneManager instance] settingsStore] != Nil) [[[LinphoneManager instance] settingsStore] synchronize]; - return [self enterBackgroundMode]; + linphone_core_stop_dtmf_stream(theLinphoneCore); + return YES; } - (BOOL)enterBackgroundMode { LinphoneProxyConfig* proxyCfg; linphone_core_get_default_proxy(theLinphoneCore, &proxyCfg); - linphone_core_stop_dtmf_stream(theLinphoneCore); - if (proxyCfg && [settingsStore boolForKey:@"backgroundmode_preference"]) { + + if (proxyCfg && [[NSUserDefaults standardUserDefaults] boolForKey:@"backgroundmode_preference"]) { //For registration register linphone_core_refresh_registers(theLinphoneCore); - //wait for registration answer int i=0; while (!linphone_proxy_config_is_registered(proxyCfg) && i++<40 ) { diff --git a/Settings/InAppSettings.bundle/Call.plist b/Settings/InAppSettings.bundle/Call.plist index 8e0cb92ca..b5e1a7f6d 100644 --- a/Settings/InAppSettings.bundle/Call.plist +++ b/Settings/InAppSettings.bundle/Call.plist @@ -36,7 +36,7 @@ Type PSToggleSwitchSpecifier Title - Enable RFC DTMF + Send inband DTMFs Key rfc_dtmf_preference DefaultValue @@ -46,7 +46,7 @@ Type PSToggleSwitchSpecifier Title - Enable SIPINFO DTMF + Send SIP INFO DTMFs Key sipinfo_dtmf_preference DefaultValue From ce208db0d263bd63019b00f772b03c34c65fd83c Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Thu, 16 Aug 2012 10:18:40 +0200 Subject: [PATCH 11/12] Add image picker during contact edition --- Classes/ContactDetailsImagePickerController.h | 35 ++++++++ Classes/ContactDetailsImagePickerController.m | 81 +++++++++++++++++++ Classes/ContactDetailsLabelViewController.m | 3 +- Classes/ContactDetailsTableViewController.m | 2 +- Classes/LinphoneUI/UIContactDetailsHeader.h | 7 +- Classes/LinphoneUI/UIContactDetailsHeader.m | 35 ++++++++ Classes/LinphoneUI/UIContactDetailsHeader.xib | 67 ++++++++++++++- Classes/PhoneMainView.h | 2 + linphone.xcodeproj/project.pbxproj | 8 ++ 9 files changed, 234 insertions(+), 6 deletions(-) create mode 100644 Classes/ContactDetailsImagePickerController.h create mode 100644 Classes/ContactDetailsImagePickerController.m diff --git a/Classes/ContactDetailsImagePickerController.h b/Classes/ContactDetailsImagePickerController.h new file mode 100644 index 000000000..eea057bf5 --- /dev/null +++ b/Classes/ContactDetailsImagePickerController.h @@ -0,0 +1,35 @@ +/* ContactDetailsImagePickerController.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 "UICompositeViewController.h" + +@protocol ContactDetailsImagePickerDelegate + +- (void)changeContactImage:(UIImage*)image; + +@end + +@interface ContactDetailsImagePickerController : UIImagePickerController { +@private + id imagePickerDelegate; +} + +@property (nonatomic, retain) id imagePickerDelegate; + +@end diff --git a/Classes/ContactDetailsImagePickerController.m b/Classes/ContactDetailsImagePickerController.m new file mode 100644 index 000000000..3f321ce45 --- /dev/null +++ b/Classes/ContactDetailsImagePickerController.m @@ -0,0 +1,81 @@ +/* ContactDetailsImagePickerController.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 "ContactDetailsImagePickerController.h" +#import "PhoneMainView.h" + +@implementation ContactDetailsImagePickerController + +@synthesize imagePickerDelegate; + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if(compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:@"ContactDetailsImage" + content:@"ContactDetailsImagePickerController" + stateBar:nil + stateBarEnabled:false + tabBar:@"UIMainBar" + tabBarEnabled:true + fullscreen:false + landscapeMode:[LinphoneManager runningOnIpad] + portraitMode:true]; + } + return compositeDescription; +} + + +#pragma mark - ViewController Functions + +- (void)viewDidLoad { + [super viewDidLoad]; + [self setDelegate:self]; +} + + +#pragma mark - + +- (void)dismiss { + if([[[PhoneMainView instance] currentView] equal:[ContactDetailsImagePickerController compositeViewDescription]]) { + [[PhoneMainView instance] popCurrentView]; + } +} + + +#pragma mark - UIImagePickerControllerDelegate Functions + +- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { + UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage]; + if(image == nil) { + image = [info objectForKey:UIImagePickerControllerOriginalImage]; + } + if(image != nil) { + [imagePickerDelegate changeContactImage:image]; + } + [self dismiss]; +} + +- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { + [self dismiss]; +} + +@end diff --git a/Classes/ContactDetailsLabelViewController.m b/Classes/ContactDetailsLabelViewController.m index be5a95f12..c63b70abf 100644 --- a/Classes/ContactDetailsLabelViewController.m +++ b/Classes/ContactDetailsLabelViewController.m @@ -64,7 +64,7 @@ static UICompositeViewDescription *compositeDescription = nil; tabBar:@"UIMainBar" tabBarEnabled:true fullscreen:false - landscapeMode:true + landscapeMode:[LinphoneManager runningOnIpad] portraitMode:true]; } return compositeDescription; @@ -79,6 +79,7 @@ static UICompositeViewDescription *compositeDescription = nil; } } + #pragma mark - Property Functions - (void)setDataList:(NSDictionary *)adatalist { diff --git a/Classes/ContactDetailsTableViewController.m b/Classes/ContactDetailsTableViewController.m index 580772ff8..f0cee1c8d 100644 --- a/Classes/ContactDetailsTableViewController.m +++ b/Classes/ContactDetailsTableViewController.m @@ -490,7 +490,7 @@ static const int contactSections[ContactSections_MAX] = {ContactSections_None, C } else { // Go to Chat room view [[PhoneMainView instance] popToView:[ChatViewController compositeViewDescription]]; - ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController); + ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription]], ChatRoomViewController); if(controller != nil) { [controller setRemoteAddress:dest]; } diff --git a/Classes/LinphoneUI/UIContactDetailsHeader.h b/Classes/LinphoneUI/UIContactDetailsHeader.h index 7e45e9514..79cb1dd1b 100644 --- a/Classes/LinphoneUI/UIContactDetailsHeader.h +++ b/Classes/LinphoneUI/UIContactDetailsHeader.h @@ -20,9 +20,10 @@ #import #import +#import "ContactDetailsImagePickerController.h" #import "ContactDetailsDelegate.h" -@interface UIContactDetailsHeader : UIViewController { +@interface UIContactDetailsHeader : UIViewController { UILabel *addressLabel; UIImageView *avatarImage; UIView *normalView; @@ -45,7 +46,9 @@ @property (nonatomic, retain) IBOutlet UITableView *tableView; @property (nonatomic, retain) IBOutlet id contactDetailsDelegate; -@property(nonatomic,getter=isEditing) BOOL editing; +@property(nonatomic,getter=isEditing) BOOL editing; + +- (IBAction)onAvatarClick:(id)event; + (CGFloat)height:(BOOL)editing; diff --git a/Classes/LinphoneUI/UIContactDetailsHeader.m b/Classes/LinphoneUI/UIContactDetailsHeader.m index 5e0de1c51..c7e0dce04 100644 --- a/Classes/LinphoneUI/UIContactDetailsHeader.m +++ b/Classes/LinphoneUI/UIContactDetailsHeader.m @@ -22,6 +22,7 @@ #import "UIEditableTableViewCell.h" #import "FastAddressBook.h" #import "UILinphone.h" +#import "PhoneMainView.h" @implementation UIContactDetailsHeader @@ -231,6 +232,40 @@ } +#pragma mark - Action Functions + +- (IBAction)onAvatarClick:(id)event { + if(self.isEditing) { + ContactDetailsImagePickerController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsImagePickerController compositeViewDescription] push:TRUE], ContactDetailsImagePickerController); + if(controller != nil) { + [controller setAllowsEditing:TRUE]; + [controller setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; + [controller setImagePickerDelegate:self]; + } + } +} + + +#pragma mark - ContactDetailsImagePickerDelegate Functions + +- (void)changeContactImage:(UIImage*)image { + NSError* error = NULL; + if(!ABPersonRemoveImageData(contact, (CFErrorRef*)error)) { + [LinphoneLogger log:LinphoneLoggerLog format:@"Can't add entry: %@", [error localizedDescription]]; + } + NSData *dataRef = UIImagePNGRepresentation(image); + CFDataRef cfdata = CFDataCreate(NULL,[dataRef bytes], [dataRef length]); + + if(!ABPersonSetImageData(contact, cfdata, (CFErrorRef*)error)) { + [LinphoneLogger log:LinphoneLoggerLog format:@"Can't add entry: %@", [error localizedDescription]]; + } + + CFRelease(cfdata); + + [self update]; +} + + #pragma mark - UITableViewDelegate Functions - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { diff --git a/Classes/LinphoneUI/UIContactDetailsHeader.xib b/Classes/LinphoneUI/UIContactDetailsHeader.xib index 2ad58ddc6..ee6cd04d7 100644 --- a/Classes/LinphoneUI/UIContactDetailsHeader.xib +++ b/Classes/LinphoneUI/UIContactDetailsHeader.xib @@ -12,6 +12,7 @@ IBProxyObject + IBUIButton IBUIImageView IBUILabel IBUITableView @@ -58,7 +59,7 @@ {{20, 6}, {65, 65}} - + _NS:9 NO IBCocoaTouchFramework @@ -67,6 +68,40 @@ avatar_unknown_small.png + + + 292 + {{20, 6}, {65, 65}} + + + + _NS:9 + NO + IBCocoaTouchFramework + 0 + 0 + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + 290 @@ -277,6 +312,15 @@ AAgACAAIAAEAAQABAAE 19 + + + onAvatarClick: + + + 7 + + 23 + @@ -305,6 +349,7 @@ AAgACAAIAAEAAQABAAE + @@ -349,6 +394,12 @@ AAgACAAIAAEAAQABAAE + + 22 + + + avatarButton + @@ -359,6 +410,7 @@ AAgACAAIAAEAAQABAAE com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -368,13 +420,24 @@ AAgACAAIAAEAAQABAAE - 21 + 23 UIContactDetailsHeader UIViewController + + onImageClick: + id + + + onImageClick: + + onImageClick: + id + + UILabel UIImageView diff --git a/Classes/PhoneMainView.h b/Classes/PhoneMainView.h index 6217ae92d..68e4bf9f2 100644 --- a/Classes/PhoneMainView.h +++ b/Classes/PhoneMainView.h @@ -29,6 +29,8 @@ #import "DialerViewController.h" #import "ContactsViewController.h" #import "ContactDetailsViewController.h" +#import "ContactDetailsLabelViewController.h" +#import "ContactDetailsImagePickerController.h" #import "HistoryViewController.h" #import "HistoryDetailsViewController.h" #import "InCallViewController.h" diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index d809609ee..7c435be7b 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -674,6 +674,8 @@ D378906515AC373B00BD776C /* ContactDetailsLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D378906315AC373B00BD776C /* ContactDetailsLabelViewController.m */; }; D378906615AC373B00BD776C /* ContactDetailsLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D378906315AC373B00BD776C /* ContactDetailsLabelViewController.m */; }; D378906715AC373B00BD776C /* ContactDetailsLabelViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D378906415AC373B00BD776C /* ContactDetailsLabelViewController.xib */; }; + D378AB2A15DCDB4A0098505D /* ContactDetailsImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = D378AB2915DCDB490098505D /* ContactDetailsImagePickerController.m */; }; + D378AB2B15DCDB4A0098505D /* ContactDetailsImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = D378AB2915DCDB490098505D /* ContactDetailsImagePickerController.m */; }; D37B96B715A1A6F20005CCD2 /* call_state_delete_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D37B96B515A1A6F20005CCD2 /* call_state_delete_default.png */; }; D37B96B915A1A6F20005CCD2 /* call_state_delete_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D37B96B615A1A6F20005CCD2 /* call_state_delete_over.png */; }; D37C638E15AAD251009D0BAC /* contact_number_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D37C638C15AAD251009D0BAC /* contact_number_over.png */; }; @@ -1674,6 +1676,8 @@ D378906215AC373B00BD776C /* ContactDetailsLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsLabelViewController.h; sourceTree = ""; }; D378906315AC373B00BD776C /* ContactDetailsLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailsLabelViewController.m; sourceTree = ""; }; D378906415AC373B00BD776C /* ContactDetailsLabelViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContactDetailsLabelViewController.xib; sourceTree = ""; }; + D378AB2815DCDB480098505D /* ContactDetailsImagePickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsImagePickerController.h; sourceTree = ""; }; + D378AB2915DCDB490098505D /* ContactDetailsImagePickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailsImagePickerController.m; sourceTree = ""; }; D37B96B515A1A6F20005CCD2 /* call_state_delete_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_delete_default.png; path = Resources/call_state_delete_default.png; sourceTree = ""; }; D37B96B615A1A6F20005CCD2 /* call_state_delete_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_delete_over.png; path = Resources/call_state_delete_over.png; sourceTree = ""; }; D37C638C15AAD251009D0BAC /* contact_number_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_number_over.png; path = Resources/contact_number_over.png; sourceTree = ""; }; @@ -2152,6 +2156,8 @@ 22E0A81F111C44E100B04932 /* ConsoleViewController.m */, 22E0A81E111C44E100B04932 /* ConsoleViewController.xib */, D30BBD1215D3EFEB000F93DD /* ContactDetailsDelegate.h */, + D378AB2815DCDB480098505D /* ContactDetailsImagePickerController.h */, + D378AB2915DCDB490098505D /* ContactDetailsImagePickerController.m */, D378906215AC373B00BD776C /* ContactDetailsLabelViewController.h */, D378906315AC373B00BD776C /* ContactDetailsLabelViewController.m */, D378906415AC373B00BD776C /* ContactDetailsLabelViewController.xib */, @@ -4312,6 +4318,7 @@ D380800215C2894A005BE9BC /* IASKTextField.m in Sources */, D380800515C28A7A005BE9BC /* UILinphone.m in Sources */, D380801315C299D0005BE9BC /* ColorSpaceUtilites.m in Sources */, + D378AB2A15DCDB4A0098505D /* ContactDetailsImagePickerController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4401,6 +4408,7 @@ D380800315C2894A005BE9BC /* IASKTextField.m in Sources */, D380800615C28A7A005BE9BC /* UILinphone.m in Sources */, D380801415C299D0005BE9BC /* ColorSpaceUtilites.m in Sources */, + D378AB2B15DCDB4A0098505D /* ContactDetailsImagePickerController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 27ad4bbee80f6657c586c3b9ebb34fc639daa184 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Thu, 16 Aug 2012 14:30:04 +0200 Subject: [PATCH 12/12] Fix previous commit: Chat/ChatRoom view stack issue --- Classes/ContactDetailsImagePickerController.m | 1 + Classes/ContactDetailsTableViewController.m | 4 ++-- Classes/PhoneMainView.m | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Classes/ContactDetailsImagePickerController.m b/Classes/ContactDetailsImagePickerController.m index 3f321ce45..0b68fcf1b 100644 --- a/Classes/ContactDetailsImagePickerController.m +++ b/Classes/ContactDetailsImagePickerController.m @@ -24,6 +24,7 @@ @synthesize imagePickerDelegate; + #pragma mark - UICompositeViewDelegate Functions static UICompositeViewDescription *compositeDescription = nil; diff --git a/Classes/ContactDetailsTableViewController.m b/Classes/ContactDetailsTableViewController.m index f0cee1c8d..784efef47 100644 --- a/Classes/ContactDetailsTableViewController.m +++ b/Classes/ContactDetailsTableViewController.m @@ -489,8 +489,8 @@ static const int contactSections[ContactSections_MAX] = {ContactSections_None, C } } else { // Go to Chat room view - [[PhoneMainView instance] popToView:[ChatViewController compositeViewDescription]]; - ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription]], ChatRoomViewController); + [[PhoneMainView instance] popToView:[ChatViewController compositeViewDescription]]; // Got to Chat and push ChatRoom + ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController); if(controller != nil) { [controller setRemoteAddress:dest]; } diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index d86226176..390201f3d 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -516,7 +516,7 @@ static PhoneMainView* phoneMainViewInstance=nil; - (UIViewController*)popCurrentView { [LinphoneLogger logc:LinphoneLoggerLog format:"PhoneMainView: Pop view"]; - if([viewStack count] > 0) { + if([viewStack count] > 1) { [viewStack removeLastObject]; [self _changeCurrentView:[viewStack lastObject] transition:[PhoneMainView getBackwardTransition] force:TRUE]; return [mainViewController getCurrentViewController];