From d42c91f80234bad9523ae92fca4c3bd4337bdffe Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Thu, 24 May 2012 13:12:00 +0200 Subject: [PATCH 1/8] In app settings WIP --- Classes/LinphoneAppDelegate.h | 11 +- Classes/LinphoneAppDelegate.m | 59 +- Classes/LinphoneCoreSettingsStore.h | 15 + Classes/LinphoneCoreSettingsStore.m | 61 ++ Classes/LinphoneUI/LinphoneManager.h | 5 +- Classes/LinphoneUI/LinphoneManager.m | 49 ++ .../IASKAppSettingsViewController.h | 84 ++ .../IASKAppSettingsViewController.m | 798 ++++++++++++++++++ .../IASKAppSettingsWebViewController.h | 30 + .../IASKAppSettingsWebViewController.m | 148 ++++ .../IASKSpecifierValuesViewController.h | 36 + .../IASKSpecifierValuesViewController.m | 195 +++++ .../Controllers/IASKViewController.h | 26 + InAppSettingsKit/Models/IASKSettingsReader.h | 149 ++++ InAppSettingsKit/Models/IASKSettingsReader.m | 278 ++++++ InAppSettingsKit/Models/IASKSettingsStore.h | 39 + InAppSettingsKit/Models/IASKSettingsStore.m | 68 ++ .../Models/IASKSettingsStoreFile.h | 28 + .../Models/IASKSettingsStoreFile.m | 54 ++ .../Models/IASKSettingsStoreUserDefaults.h | 25 + .../Models/IASKSettingsStoreUserDefaults.m | 67 ++ InAppSettingsKit/Models/IASKSpecifier.h | 59 ++ InAppSettingsKit/Models/IASKSpecifier.m | 240 ++++++ .../Views/IASKPSSliderSpecifierViewCell.h | 31 + .../Views/IASKPSSliderSpecifierViewCell.m | 72 ++ .../Views/IASKPSTextFieldSpecifierViewCell.h | 29 + .../Views/IASKPSTextFieldSpecifierViewCell.m | 52 ++ .../Views/IASKPSTitleValueSpecifierViewCell.h | 22 + .../Views/IASKPSTitleValueSpecifierViewCell.m | 57 ++ .../IASKPSToggleSwitchSpecifierViewCell.h | 29 + .../IASKPSToggleSwitchSpecifierViewCell.m | 62 ++ InAppSettingsKit/Views/IASKSlider.h | 26 + InAppSettingsKit/Views/IASKSlider.m | 30 + InAppSettingsKit/Views/IASKSwitch.h | 26 + InAppSettingsKit/Views/IASKSwitch.m | 31 + InAppSettingsKit/Views/IASKTextField.h | 26 + InAppSettingsKit/Views/IASKTextField.m | 30 + InAppSettingsKit/Xibs/IASKAppSettingsView.xib | 222 +++++ .../Xibs/IASKAppSettingsWebView.xib | 378 +++++++++ .../Xibs/IASKPSSliderSpecifierViewCell.xib | 251 ++++++ .../Xibs/IASKPSTextFieldSpecifierViewCell.xib | 254 ++++++ .../IASKPSToggleSwitchSpecifierViewCell.xib | 237 ++++++ .../Xibs/IASKSpecifierValuesView.xib | 255 ++++++ PhoneMainView.xib | 403 +++++++-- Settings.bundle/Root.plist | 10 + Settings.bundle/video.plist | 10 - linphone.xcodeproj/project.pbxproj | 214 +++++ submodules/linphone | 2 +- 48 files changed, 5146 insertions(+), 137 deletions(-) create mode 100644 Classes/LinphoneCoreSettingsStore.h create mode 100644 Classes/LinphoneCoreSettingsStore.m create mode 100644 InAppSettingsKit/Controllers/IASKAppSettingsViewController.h create mode 100644 InAppSettingsKit/Controllers/IASKAppSettingsViewController.m create mode 100644 InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h create mode 100644 InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m create mode 100644 InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h create mode 100644 InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m create mode 100644 InAppSettingsKit/Controllers/IASKViewController.h create mode 100644 InAppSettingsKit/Models/IASKSettingsReader.h create mode 100644 InAppSettingsKit/Models/IASKSettingsReader.m create mode 100644 InAppSettingsKit/Models/IASKSettingsStore.h create mode 100644 InAppSettingsKit/Models/IASKSettingsStore.m create mode 100644 InAppSettingsKit/Models/IASKSettingsStoreFile.h create mode 100644 InAppSettingsKit/Models/IASKSettingsStoreFile.m create mode 100644 InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.h create mode 100644 InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.m create mode 100644 InAppSettingsKit/Models/IASKSpecifier.h create mode 100644 InAppSettingsKit/Models/IASKSpecifier.m create mode 100644 InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h create mode 100644 InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m create mode 100644 InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h create mode 100644 InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m create mode 100644 InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.h create mode 100644 InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.m create mode 100644 InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.h create mode 100644 InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.m create mode 100644 InAppSettingsKit/Views/IASKSlider.h create mode 100644 InAppSettingsKit/Views/IASKSlider.m create mode 100644 InAppSettingsKit/Views/IASKSwitch.h create mode 100644 InAppSettingsKit/Views/IASKSwitch.m create mode 100644 InAppSettingsKit/Views/IASKTextField.h create mode 100644 InAppSettingsKit/Views/IASKTextField.m create mode 100644 InAppSettingsKit/Xibs/IASKAppSettingsView.xib create mode 100644 InAppSettingsKit/Xibs/IASKAppSettingsWebView.xib create mode 100644 InAppSettingsKit/Xibs/IASKPSSliderSpecifierViewCell.xib create mode 100644 InAppSettingsKit/Xibs/IASKPSTextFieldSpecifierViewCell.xib create mode 100644 InAppSettingsKit/Xibs/IASKPSToggleSwitchSpecifierViewCell.xib create mode 100644 InAppSettingsKit/Xibs/IASKSpecifierValuesView.xib diff --git a/Classes/LinphoneAppDelegate.h b/Classes/LinphoneAppDelegate.h index f5e9508a1..8c7b21827 100644 --- a/Classes/LinphoneAppDelegate.h +++ b/Classes/LinphoneAppDelegate.h @@ -21,11 +21,13 @@ #import #import #import "CoreTelephony/CTCallCenter.h" +#import "IASKAppSettingsViewController.h" +#define HISTORY_TAB_INDEX 0 #define DIALER_TAB_INDEX 1 #define CONTACTS_TAB_INDEX 2 -#define HISTORY_TAB_INDEX 0 -#define MORE_TAB_INDEX 3 +#define SETTINGS_TAB_INDEX 3 +#define MORE_TAB_INDEX 4 @class ContactPickerDelegate; @class IncallViewController; @@ -38,6 +40,8 @@ IBOutlet UITabBarController* myTabBarController; IBOutlet ABPeoplePickerNavigationController* myPeoplePickerController; IBOutlet PhoneViewController* myPhoneViewController; + IBOutlet UINavigationController* moreNavigationController; + IBOutlet IASKAppSettingsViewController* settingsController; CallHistoryTableViewController* myCallHistoryTableViewController; ContactPickerDelegate* myContactPickerDelegate; @@ -53,8 +57,9 @@ @property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain) IBOutlet UITabBarController* myTabBarController; @property (nonatomic, retain) ABPeoplePickerNavigationController* myPeoplePickerController; +@property (nonatomic, retain) IBOutlet UINavigationController* moreNavigationController; @property (nonatomic, retain) IBOutlet PhoneViewController* myPhoneViewController; - +@property (nonatomic, retain) IBOutlet IASKAppSettingsViewController* settingsController; @end diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 8162f851d..3807085f7 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -45,6 +45,8 @@ int __aeabi_idiv(int a, int b) { @synthesize myTabBarController; @synthesize myPeoplePickerController; @synthesize myPhoneViewController; +@synthesize moreNavigationController; +@synthesize settingsController; -(void) handleGSMCallInteration: (id) cCenter { CTCallCenter* ct = (CTCallCenter*) cCenter; @@ -167,43 +169,20 @@ int __aeabi_idiv(int a, int b) { } -(void) setupUI { - //as defined in PhoneMainView.xib - //dialer - myPhoneViewController = (PhoneViewController*) [myTabBarController.viewControllers objectAtIndex: DIALER_TAB_INDEX]; - myPhoneViewController.myTabBarController = myTabBarController; - //Call history - myCallHistoryTableViewController = [[CallHistoryTableViewController alloc] initWithNibName:@"CallHistoryTableViewController" - bundle:[NSBundle mainBundle]]; - UINavigationController *aCallHistNavigationController = [[UINavigationController alloc] initWithRootViewController:myCallHistoryTableViewController]; - aCallHistNavigationController.tabBarItem = [(UIViewController*)[myTabBarController.viewControllers objectAtIndex:HISTORY_TAB_INDEX] tabBarItem]; - - //people picker delegates + // Contacts myContactPickerDelegate = [[ContactPickerDelegate alloc] init]; - //people picker - myPeoplePickerController = [[[ABPeoplePickerNavigationController alloc] init] autorelease]; - [myPeoplePickerController setDisplayedProperties:[NSArray arrayWithObject:[NSNumber numberWithInt:kABPersonPhoneProperty]]]; - [myPeoplePickerController setPeoplePickerDelegate:myContactPickerDelegate]; - //copy tab bar item - myPeoplePickerController.tabBarItem = [(UIViewController*)[myTabBarController.viewControllers objectAtIndex:CONTACTS_TAB_INDEX] tabBarItem]; - - //more tab - MoreViewController *moreViewController = [[MoreViewController alloc] initWithNibName:@"MoreViewController" bundle:[NSBundle mainBundle]]; - UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:moreViewController]; - [moreViewController release]; - //copy tab bar item - aNavigationController.tabBarItem = [(UIViewController*)[myTabBarController.viewControllers objectAtIndex:MORE_TAB_INDEX] tabBarItem]; - - //insert contact controller - NSMutableArray* newArray = [NSMutableArray arrayWithArray:self.myTabBarController.viewControllers]; - [newArray replaceObjectAtIndex:CONTACTS_TAB_INDEX withObject:myPeoplePickerController]; - [newArray replaceObjectAtIndex:MORE_TAB_INDEX withObject:aNavigationController]; - [aNavigationController release]; - [newArray replaceObjectAtIndex:HISTORY_TAB_INDEX withObject:aCallHistNavigationController]; - [aCallHistNavigationController release]; - - [myTabBarController setSelectedIndex:DIALER_TAB_INDEX]; - [myTabBarController setViewControllers:newArray animated:NO]; - + //people picker + myPeoplePickerController = [[[ABPeoplePickerNavigationController alloc] init] autorelease]; + [myPeoplePickerController setDisplayedProperties:[NSArray arrayWithObject:[NSNumber numberWithInt:kABPersonPhoneProperty]]]; + [myPeoplePickerController setPeoplePickerDelegate:myContactPickerDelegate]; + //copy tab bar item + myPeoplePickerController.tabBarItem = [(UIViewController*)[myTabBarController.viewControllers objectAtIndex:CONTACTS_TAB_INDEX] tabBarItem]; + + NSMutableArray* newArray = [NSMutableArray arrayWithArray:self.myTabBarController.viewControllers]; + [newArray replaceObjectAtIndex:CONTACTS_TAB_INDEX withObject:myPeoplePickerController]; + [myTabBarController setViewControllers:newArray animated:NO]; + + [myTabBarController setSelectedIndex:DIALER_TAB_INDEX]; [window addSubview:myTabBarController.view]; [window makeKeyAndVisible]; @@ -257,6 +236,12 @@ int __aeabi_idiv(int a, int b) { [[LinphoneManager instance] startLibLinphone]; + // Settings, setup delegate + settingsController.delegate = [LinphoneManager instance]; + settingsController.settingsReader.delegate = [LinphoneManager instance]; + [settingsController.settingsReader init]; + + [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound]; [self setupGSMInteraction]; @@ -282,6 +267,4 @@ int __aeabi_idiv(int a, int b) { linphone_core_accept_call([LinphoneManager getLc], call); } - - @end diff --git a/Classes/LinphoneCoreSettingsStore.h b/Classes/LinphoneCoreSettingsStore.h new file mode 100644 index 000000000..bb9df882a --- /dev/null +++ b/Classes/LinphoneCoreSettingsStore.h @@ -0,0 +1,15 @@ +// +// LinphoneCoreSettingsStore.h +// linphone +// +// Created by Pierre-Eric Pelloux-Prayer on 22/05/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import +#import "IASKSettingsStore.h" + +@interface LinphoneCoreSettingsStore : IASKAbstractSettingsStore { +} + +@end diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m new file mode 100644 index 000000000..f9f9d8f62 --- /dev/null +++ b/Classes/LinphoneCoreSettingsStore.m @@ -0,0 +1,61 @@ +// +// LinphoneCoreSettingsStore.m +// linphone +// +// Created by Pierre-Eric Pelloux-Prayer on 22/05/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "LinphoneCoreSettingsStore.h" + + +debugenable_preference +transport_preference +username_preference +domain_preference +password_preference +check_config_disable_preference +outbound_proxy_preference +proxy_preference +prefix_preference +substitute_+_by_00_preference +wifi_only_preference + +silk_24k_preference +speex_16k_preference +speex_8k_preference +silk_16k_preference +amr_8k_preference +gsm_8k_preference +ilbc_preference +pcmu_preference +pcma_preference +g722_preferenceg +g729_preference + +mp4v-es_preference +h264_preference +vp8_preference + +enable_video_preference +enable_srtp_preference +stun_preference +start_video_preference +backgroundmode_preference + +@implementation LinphoneCoreSettingsStore + + +-(void) setObject:(id)value forKey:(NSString *)key { + + +} + +- (id)objectForKey:(NSString*)key { + return nil; +} +- (BOOL)synchronize { + return YES; +} + +@end diff --git a/Classes/LinphoneUI/LinphoneManager.h b/Classes/LinphoneUI/LinphoneManager.h index a52cff965..b2f4dfc3d 100644 --- a/Classes/LinphoneUI/LinphoneManager.h +++ b/Classes/LinphoneUI/LinphoneManager.h @@ -23,6 +23,8 @@ #include "linphonecore.h" #import "LogView.h" #import "LinphoneUIDelegates.h" +#import "IASKSettingsReader.h" +#import "IASKAppSettingsViewController.h" typedef enum _Connectivity { wifi, @@ -49,7 +51,7 @@ typedef struct _LinphoneCallAppData { } LinphoneCallAppData; -@interface LinphoneManager : NSObject { +@interface LinphoneManager : NSObject { @protected SCNetworkReachabilityRef proxyReachability; @private @@ -99,5 +101,6 @@ typedef struct _LinphoneCallAppData { @property Connectivity connectivity; @property (readonly) const char* frontCamId; @property (readonly) const char* backCamId; +@property (nonatomic) bool isbackgroundModeEnabled; @end diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index 540ae63ec..50a632aee 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -56,6 +56,7 @@ extern void libmsbcg729_init(); @synthesize connectivity; @synthesize frontCamId; @synthesize backCamId; +@synthesize isbackgroundModeEnabled; -(id) init { assert (!theLinphoneManager); @@ -1069,5 +1070,53 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach ms_message("UI - '%s' pressed", name); } +-(void) settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender { + [self reconfigureLinphoneIfNeeded: currentSettings]; +} + +-(NSDictionary*) filterPreferenceSpecifier:(NSDictionary *)specifier { + if (!theLinphoneCore) { + // LinphoneCore not ready: do not filter + return specifier; + } + NSString* identifier = [specifier objectForKey:@"Identifier"]; + if (identifier == nil) { + identifier = [specifier objectForKey:@"Key"]; + } + if (!identifier) { + // child pane maybe + NSString* title = [specifier objectForKey:@"Title"]; + if ([title isEqualToString:@"Video"]) { + if (!linphone_core_video_enabled(theLinphoneCore)) + return nil; + } + return specifier; + } + // NSLog(@"Specifier received: %@", identifier); + if ([identifier isEqualToString:@"srtp_preference"]) { + if (!ortp_srtp_supported()) + return nil; + } else if ([identifier hasPrefix:@"silk"]) { + if ([identifier isEqualToString:@"speex_24k_preference"]) { + if (linphone_core_find_payload_type(theLinphoneCore, "SILK", 24000)) return nil; + } else if ([identifier isEqualToString:@"speex_16k_preference"]) { + if (linphone_core_find_payload_type(theLinphoneCore, "SILK", 16000)) return nil; + } else if ([identifier isEqualToString:@"speex_8k_preference"]) { + if (linphone_core_find_payload_type(theLinphoneCore, "SILK", 8000)) return nil; + } + } else if ([identifier isEqualToString:@"backgroundmode_preference"]) { + UIDevice* device = [UIDevice currentDevice]; + if ([device respondsToSelector:@selector(isMultitaskingSupported)]) { + if ([device isMultitaskingSupported]) { + return specifier; + } + } + // hide setting if bg mode not supported + return nil; + } + return specifier; +} + + @end diff --git a/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h new file mode 100644 index 000000000..2eaaa2ca0 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h @@ -0,0 +1,84 @@ +// +// IASKAppSettingsViewController.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import + +#import "IASKSettingsStore.h" +#import "IASKViewController.h" + +@class IASKSettingsReader; +@class IASKAppSettingsViewController; +@class IASKSpecifier; + +@protocol IASKSettingsDelegate +- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController*)sender; + +@optional +#pragma mark - UITableView header customization +- (CGFloat) settingsViewController:(id)settingsViewController + tableView:(UITableView *)tableView + heightForHeaderForSection:(NSInteger)section; +- (UIView *) settingsViewController:(id)settingsViewController + tableView:(UITableView *)tableView + viewForHeaderForSection:(NSInteger)section; + +#pragma mark - UITableView cell customization +- (CGFloat)tableView:(UITableView*)tableView heightForSpecifier:(IASKSpecifier*)specifier; +- (UITableViewCell*)tableView:(UITableView*)tableView cellForSpecifier:(IASKSpecifier*)specifier; + +#pragma mark - mail composing customization +- (NSString*) settingsViewController:(id)settingsViewController + mailComposeBodyForSpecifier:(IASKSpecifier*) specifier; + +- (UIViewController*) settingsViewController:(id)settingsViewController + viewControllerForMailComposeViewForSpecifier:(IASKSpecifier*) specifier; + +- (void) settingsViewController:(id) settingsViewController + mailComposeController:(MFMailComposeViewController*)controller + didFinishWithResult:(MFMailComposeResult)result + error:(NSError*)error; + +#pragma mark - respond to button taps +- (void)settingsViewController:(IASKAppSettingsViewController*)sender buttonTappedForKey:(NSString*)key; +- (void)settingsViewController:(IASKAppSettingsViewController*)sender tableView:(UITableView *)tableView didSelectCustomViewSpecifier:(IASKSpecifier*)specifier; +@end + + +@interface IASKAppSettingsViewController : UITableViewController { + id _delegate; + + NSMutableArray *_viewList; + + IASKSettingsReader *_settingsReader; + id _settingsStore; + NSString *_file; + + id _currentFirstResponder; + + BOOL _showCreditsFooter; + BOOL _showDoneButton; +} + +@property (nonatomic, assign) IBOutlet id delegate; +@property (nonatomic, copy) NSString *file; +@property (nonatomic, assign) BOOL showCreditsFooter; +@property (nonatomic, assign) BOOL showDoneButton; + +- (void)synchronizeSettings; +- (IBAction)dismiss:(id)sender; + +@end diff --git a/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m new file mode 100644 index 000000000..d3593e1b0 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m @@ -0,0 +1,798 @@ +// +// IASKAppSettingsViewController.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009-2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + + +#import "IASKAppSettingsViewController.h" +#import "IASKSettingsReader.h" +#import "IASKSettingsStoreUserDefaults.h" +#import "IASKPSToggleSwitchSpecifierViewCell.h" +#import "IASKPSSliderSpecifierViewCell.h" +#import "IASKPSTextFieldSpecifierViewCell.h" +#import "IASKPSTitleValueSpecifierViewCell.h" +#import "IASKSwitch.h" +#import "IASKSlider.h" +#import "IASKSpecifier.h" +#import "IASKSpecifierValuesViewController.h" +#import "IASKTextField.h" + +static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3; +static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2; +static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8; + +static NSString *kIASKCredits = @"Powered by InAppSettingsKit"; // Leave this as-is!!! + +#define kIASKSpecifierValuesViewControllerIndex 0 +#define kIASKSpecifierChildViewControllerIndex 1 + +#define kIASKCreditsViewWidth 285 + +CGRect IASKCGRectSwap(CGRect rect); + +@interface IASKAppSettingsViewController () +@property (nonatomic, retain) NSMutableArray *viewList; +@property (nonatomic, retain) id currentFirstResponder; + +- (void) setup; + +- (void)_textChanged:(id)sender; +- (void)synchronizeSettings; +- (void)userDefaultsDidChange; +- (void)reload; +@end + +@implementation IASKAppSettingsViewController + +@synthesize delegate = _delegate; +@synthesize viewList = _viewList; +@synthesize settingsReader = _settingsReader; +@synthesize file = _file; +@synthesize currentFirstResponder = _currentFirstResponder; +@synthesize showCreditsFooter = _showCreditsFooter; +@synthesize showDoneButton = _showDoneButton; +@synthesize settingsStore = _settingsStore; + +#pragma mark accessors +- (IASKSettingsReader*)settingsReader { + if (!_settingsReader) { + _settingsReader = [[IASKSettingsReader alloc] initWithFile:self.file]; + } + return _settingsReader; +} + +- (id)settingsStore { + if (!_settingsStore) { + _settingsStore = [[IASKSettingsStoreUserDefaults alloc] init]; + } + return _settingsStore; +} + +- (NSString*)file { + if (!_file) { + return @"Root"; + } + return [[_file retain] autorelease]; +} + +- (void)setFile:(NSString *)file { + if (file != _file) { + + [_file release]; + _file = [file copy]; + } + + self.tableView.contentOffset = CGPointMake(0, 0); + self.settingsReader = nil; // automatically initializes itself + [self.tableView reloadData]; +} + +- (BOOL)isPad { + BOOL isPad = NO; +#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200) + isPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; +#endif + return isPad; +} + +#pragma mark standard view controller methods +- (id)init { + return [self initWithNibName:@"IASKAppSettingsView" bundle:nil]; +} + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { + // If set to YES, will add a DONE button at the right of the navigation bar + _showDoneButton = YES; + + [self setup]; + } + return self; +} + +- (void)awakeFromNib { + // If set to YES, will add a DONE button at the right of the navigation bar + // if loaded via NIB, it's likely we sit in a TabBar- or NavigationController + // and thus don't need the Done button + _showDoneButton = NO; + + [self setup]; +} + +//common (NIB & code based) initialization +- (void) setup { + // If set to YES, will display credits for InAppSettingsKit creators + _showCreditsFooter = YES; +} + +- (NSMutableArray *)viewList { + if (!_viewList) { + _viewList = [[NSMutableArray alloc] init]; + [_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKSpecifierValuesView", @"ViewName",nil]]; + [_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKAppSettingsView", @"ViewName",nil]]; + } + return _viewList; +} + +- (void) viewDidLoad { + [super viewDidLoad]; + if ([self isPad]) { + self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLineEtched; + } +} + +- (void)viewDidUnload { + [super viewDidUnload]; + + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; + self.view = nil; + self.viewList = nil; +} + +- (void)viewWillAppear:(BOOL)animated { + // if there's something selected, the value might have changed + // so reload that row + NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow]; + if(selectedIndexPath) { + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:selectedIndexPath] + withRowAnimation:UITableViewRowAnimationNone]; + // and reselect it, so we get the nice default deselect animation from UITableViewController + [self.tableView selectRowAtIndexPath:selectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; + } + + self.navigationItem.rightBarButtonItem = nil; + self.navigationController.delegate = self; + if (_showDoneButton) { + UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone + target:self + action:@selector(dismiss:)]; + self.navigationItem.rightBarButtonItem = buttonItem; + [buttonItem release]; + } + if (!self.title) { + self.title = NSLocalizedString(@"Settings", @""); + } + + if ([self.settingsStore isKindOfClass:[IASKSettingsStoreUserDefaults class]]) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(userDefaultsDidChange) + name:NSUserDefaultsDidChangeNotification + object:[NSUserDefaults standardUserDefaults]]; + [self userDefaultsDidChange]; // force update in case of changes while we were hidden + } + [super viewWillAppear:animated]; +} + +- (CGSize)contentSizeForViewInPopover { + return [[self view] sizeThatFits:CGSizeMake(320, 2000)]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + NSNotificationCenter *dc = [NSNotificationCenter defaultCenter]; + IASK_IF_IOS4_OR_GREATER([dc addObserver:self selector:@selector(synchronizeSettings) name:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication]];); + IASK_IF_IOS4_OR_GREATER([dc addObserver:self selector:@selector(reload) name:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];); + [dc addObserver:self selector:@selector(synchronizeSettings) name:UIApplicationWillTerminateNotification object:[UIApplication sharedApplication]]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [NSObject cancelPreviousPerformRequestsWithTarget:self]; + [super viewWillDisappear:animated]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + if (!self.navigationController.delegate) { + // hide the keyboard when we're popping from the navigation controller + [self.currentFirstResponder resignFirstResponder]; + } + [self dismiss:nil]; + [super viewDidDisappear:animated]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return YES; +} + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { + if (![viewController isKindOfClass:[IASKAppSettingsViewController class]] && ![viewController isKindOfClass:[IASKSpecifierValuesViewController class]]) { + [self dismiss:nil]; + } +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [_viewList release], _viewList = nil; + [_file release], _file = nil; + [_currentFirstResponder release], _currentFirstResponder = nil; + [_settingsReader release], _settingsReader = nil; + [_settingsStore release], _settingsStore = nil; + + _delegate = nil; + + [super dealloc]; +} + + +#pragma mark - +#pragma mark Actions + +- (IBAction)dismiss:(id)sender { + [self.settingsStore synchronize]; + self.navigationController.delegate = nil; + + if (self.delegate && [self.delegate conformsToProtocol:@protocol(IASKSettingsDelegate)]) { + [self.delegate settingsViewControllerDidEnd:self]; + } + // reload + [self.settingsReader initWithFile:self.file]; + [self.tableView reloadData]; +} + +- (void)toggledValue:(id)sender { + IASKSwitch *toggle = (IASKSwitch*)sender; + IASKSpecifier *spec = [_settingsReader specifierForKey:[toggle key]]; + + if ([toggle isOn]) { + if ([spec trueValue] != nil) { + [self.settingsStore setObject:[spec trueValue] forKey:[toggle key]]; + } + else { + [self.settingsStore setBool:YES forKey:[toggle key]]; + } + } + else { + if ([spec falseValue] != nil) { + [self.settingsStore setObject:[spec falseValue] forKey:[toggle key]]; + } + else { + [self.settingsStore setBool:NO forKey:[toggle key]]; + } + } + [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged + object:[toggle key] + userInfo:[NSDictionary dictionaryWithObject:[self.settingsStore objectForKey:[toggle key]] + forKey:[toggle key]]]; +} + +- (void)sliderChangedValue:(id)sender { + IASKSlider *slider = (IASKSlider*)sender; + [self.settingsStore setFloat:[slider value] forKey:[slider key]]; + [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged + object:[slider key] + userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:[slider value]] + forKey:[slider key]]]; +} + + +#pragma mark - +#pragma mark UITableView Functions + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return [self.settingsReader numberOfSections]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [self.settingsReader numberOfRowsForSection:section]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath]; + if ([[specifier type] isEqualToString:kIASKCustomViewSpecifier]) { + if ([self.delegate respondsToSelector:@selector(tableView:heightForSpecifier:)]) { + return [self.delegate tableView:tableView heightForSpecifier:specifier]; + } else { + return 0; + } + } + return tableView.rowHeight; +} + +- (NSString *)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section { + NSString *header = [self.settingsReader titleForSection:section]; + if (0 == header.length) { + return nil; + } + return header; +} + +- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section { + if ([self.delegate respondsToSelector:@selector(settingsViewController:tableView:viewForHeaderForSection:)]) { + return [self.delegate settingsViewController:self tableView:tableView viewForHeaderForSection:section]; + } else { + return nil; + } +} + +- (CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section { + if ([self tableView:tableView viewForHeaderInSection:section] && [self.delegate respondsToSelector:@selector(settingsViewController:tableView:heightForHeaderForSection:)]) { + CGFloat result; + if ((result = [self.delegate settingsViewController:self tableView:tableView heightForHeaderForSection:section])) { + return result; + } + + } + NSString *title; + if ((title = [self tableView:tableView titleForHeaderInSection:section])) { + CGSize size = [title sizeWithFont:[UIFont boldSystemFontOfSize:[UIFont labelFontSize]] + constrainedToSize:CGSizeMake(tableView.frame.size.width - 2*kIASKHorizontalPaddingGroupTitles, INFINITY) + lineBreakMode:UILineBreakModeWordWrap]; + return size.height+kIASKVerticalPaddingGroupTitles; + } + return 0; +} + +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section +{ + NSString *footerText = [self.settingsReader footerTextForSection:section]; + if (_showCreditsFooter && (section == [self.settingsReader numberOfSections]-1)) { + // show credits since this is the last section + if ((footerText == nil) || ([footerText length] == 0)) { + // show the credits on their own + return kIASKCredits; + } else { + // show the credits below the app's FooterText + return [NSString stringWithFormat:@"%@\n\n%@", footerText, kIASKCredits]; + } + } else { + if ([footerText length] == 0) { + return nil; + } + return [self.settingsReader footerTextForSection:section]; + } +} + +- (UITableViewCell*)dequeueReusableCellWithIdentifier:(NSString*)identifier { + UITableViewCell *cell = nil; + if ([identifier isEqualToString:kIASKPSToggleSwitchSpecifier]) { + cell = [[[NSBundle mainBundle] loadNibNamed:@"IASKPSToggleSwitchSpecifierViewCell" + owner:self + options:nil] objectAtIndex:0]; + } + else if ([identifier isEqualToString:kIASKPSMultiValueSpecifier] || [identifier isEqualToString:kIASKPSTitleValueSpecifier]) { + cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease]; + cell.accessoryType = [identifier isEqualToString:kIASKPSMultiValueSpecifier] ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + } + else if ([identifier isEqualToString:kIASKPSTextFieldSpecifier]) { + cell = (IASKPSTextFieldSpecifierViewCell*) [[[NSBundle mainBundle] loadNibNamed:@"IASKPSTextFieldSpecifierViewCell" + owner:self + options:nil] objectAtIndex:0]; + } + else if ([identifier isEqualToString:kIASKPSSliderSpecifier]) { + cell = (IASKPSSliderSpecifierViewCell*) [[[NSBundle mainBundle] loadNibNamed:@"IASKPSSliderSpecifierViewCell" + owner:self + options:nil] objectAtIndex:0]; + } else if ([identifier isEqualToString:kIASKPSChildPaneSpecifier]) { + cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } else if ([identifier isEqualToString:kIASKButtonSpecifier]) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease]; + } else if ([identifier isEqualToString:kIASKMailComposeSpecifier]) { + cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease]; + [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; + } else { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease]; + } + return cell; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath]; + if ([specifier.type isEqualToString:kIASKCustomViewSpecifier] && [self.delegate respondsToSelector:@selector(tableView:cellForSpecifier:)]) { + UITableViewCell* cell = [self.delegate tableView:tableView cellForSpecifier:specifier]; + assert(nil != cell && "delegate must return a UITableViewCell for custom cell types"); + return cell; + } + + UITableViewCell *cell = [self dequeueReusableCellWithIdentifier:specifier.type]; + + if ([specifier.type isEqualToString:kIASKPSToggleSwitchSpecifier]) { + ((IASKPSToggleSwitchSpecifierViewCell*)cell).label.text = specifier.title; + + id currentValue = [self.settingsStore objectForKey:specifier.key]; + BOOL toggleState; + if (currentValue) { + if ([currentValue isEqual:specifier.trueValue]) { + toggleState = YES; + } else if ([currentValue isEqual:specifier.falseValue]) { + toggleState = NO; + } else { + toggleState = [currentValue boolValue]; + } + } else { + toggleState = specifier.defaultBoolValue; + } + ((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle.on = toggleState; + + [((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle addTarget:self action:@selector(toggledValue:) forControlEvents:UIControlEventValueChanged]; + ((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle.key = specifier.key; + } + else if ([specifier.type isEqualToString:kIASKPSMultiValueSpecifier]) { + cell.textLabel.text = specifier.title; + cell.detailTextLabel.text = [[specifier titleForCurrentValue:[self.settingsStore objectForKey:specifier.key] != nil ? + [self.settingsStore objectForKey:specifier.key] : specifier.defaultValue] description]; + } + else if ([specifier.type isEqualToString:kIASKPSTitleValueSpecifier]) { + cell.textLabel.text = specifier.title; + id value = [self.settingsStore objectForKey:specifier.key] ? : specifier.defaultValue; + + NSString *stringValue; + if (specifier.multipleValues || specifier.multipleTitles) { + stringValue = [specifier titleForCurrentValue:value]; + } else { + stringValue = [value description]; + } + + cell.detailTextLabel.text = stringValue; + cell.userInteractionEnabled = NO; + } + else if ([specifier.type isEqualToString:kIASKPSTextFieldSpecifier]) { + ((IASKPSTextFieldSpecifierViewCell*)cell).label.text = specifier.title; + + NSString *textValue = [self.settingsStore objectForKey:specifier.key] != nil ? [self.settingsStore objectForKey:specifier.key] : specifier.defaultStringValue; + if (textValue && ![textValue isMemberOfClass:[NSString class]]) { + textValue = [NSString stringWithFormat:@"%@", textValue]; + } + IASKTextField *textField = ((IASKPSTextFieldSpecifierViewCell*)cell).textField; + textField.text = textValue; + textField.key = specifier.key; + textField.delegate = self; + textField.secureTextEntry = [specifier isSecure]; + textField.keyboardType = specifier.keyboardType; + textField.autocapitalizationType = specifier.autocapitalizationType; + [textField addTarget:self action:@selector(_textChanged:) forControlEvents:UIControlEventEditingChanged]; + if([specifier isSecure]){ + textField.autocorrectionType = UITextAutocorrectionTypeNo; + } else { + textField.autocorrectionType = specifier.autoCorrectionType; + } + [cell setNeedsLayout]; + } + else if ([specifier.type isEqualToString:kIASKPSSliderSpecifier]) { + if (specifier.minimumValueImage.length > 0) { + ((IASKPSSliderSpecifierViewCell*)cell).minImage.image = [UIImage imageWithContentsOfFile:[_settingsReader pathForImageNamed:specifier.minimumValueImage]]; + } + + if (specifier.maximumValueImage.length > 0) { + ((IASKPSSliderSpecifierViewCell*)cell).maxImage.image = [UIImage imageWithContentsOfFile:[_settingsReader pathForImageNamed:specifier.maximumValueImage]]; + } + + IASKSlider *slider = ((IASKPSSliderSpecifierViewCell*)cell).slider; + slider.minimumValue = specifier.minimumValue; + slider.maximumValue = specifier.maximumValue; + slider.value = [self.settingsStore objectForKey:specifier.key] != nil ? [[self.settingsStore objectForKey:specifier.key] floatValue] : [specifier.defaultValue floatValue]; + [slider addTarget:self action:@selector(sliderChangedValue:) forControlEvents:UIControlEventValueChanged]; + slider.key = specifier.key; + [cell setNeedsLayout]; + } + else if ([specifier.type isEqualToString:kIASKPSChildPaneSpecifier]) { + cell.textLabel.text = specifier.title; + } else if ([specifier.type isEqualToString:kIASKOpenURLSpecifier] || [specifier.type isEqualToString:kIASKMailComposeSpecifier]) { + cell.textLabel.text = specifier.title; + cell.detailTextLabel.text = [specifier.defaultValue description]; + } else if ([specifier.type isEqualToString:kIASKButtonSpecifier]) { + NSString *value = [self.settingsStore objectForKey:specifier.key]; + cell.textLabel.text = [value isKindOfClass:[NSString class]] ? [self.settingsReader titleForStringId:value] : specifier.title; + cell.textLabel.textAlignment = UITextAlignmentCenter; + } else { + cell.textLabel.text = specifier.title; + } + return cell; +} + +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + //create a set of specifier types that can't be selected + static NSSet* noSelectionTypes = nil; + if(nil == noSelectionTypes) { + noSelectionTypes = [[NSSet setWithObjects:kIASKPSToggleSwitchSpecifier, kIASKPSSliderSpecifier, nil] retain]; + } + + IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath]; + if([noSelectionTypes containsObject:specifier.type]) { + return nil; + } else { + return indexPath; + } +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath]; + + //switches and sliders can't be selected (should be captured by tableView:willSelectRowAtIndexPath: delegate method) + assert(![[specifier type] isEqualToString:kIASKPSToggleSwitchSpecifier]); + assert(![[specifier type] isEqualToString:kIASKPSSliderSpecifier]); + + if ([[specifier type] isEqualToString:kIASKPSMultiValueSpecifier]) { + IASKSpecifierValuesViewController *targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex] objectForKey:@"viewController"]; + + if (targetViewController == nil) { + // the view controller has not been created yet, create it and set it to our viewList array + // create a new dictionary with the new view controller + NSMutableDictionary *newItemDict = [NSMutableDictionary dictionaryWithCapacity:3]; + [newItemDict addEntriesFromDictionary: [self.viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex]]; // copy the title and explain strings + + targetViewController = [[IASKSpecifierValuesViewController alloc] initWithNibName:@"IASKSpecifierValuesView" bundle:nil]; + // add the new view controller to the dictionary and then to the 'viewList' array + [newItemDict setObject:targetViewController forKey:@"viewController"]; + [self.viewList replaceObjectAtIndex:kIASKSpecifierValuesViewControllerIndex withObject:newItemDict]; + [targetViewController release]; + + // load the view controll back in to push it + targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex] objectForKey:@"viewController"]; + } + [targetViewController setCurrentSpecifier:specifier]; + targetViewController.settingsReader = self.settingsReader; + targetViewController.settingsStore = self.settingsStore; + [[self navigationController] pushViewController:targetViewController animated:YES]; + } + else if ([[specifier type] isEqualToString:kIASKPSTextFieldSpecifier]) { + IASKPSTextFieldSpecifierViewCell *textFieldCell = (id)[tableView cellForRowAtIndexPath:indexPath]; + [textFieldCell.textField becomeFirstResponder]; + } + else if ([[specifier type] isEqualToString:kIASKPSChildPaneSpecifier]) { + + + Class vcClass = [specifier viewControllerClass]; + if (vcClass) { + SEL initSelector = [specifier viewControllerSelector]; + if (!initSelector) { + initSelector = @selector(init); + } + UIViewController * vc = [vcClass performSelector:@selector(alloc)]; + [vc performSelector:initSelector withObject:[specifier file] withObject:[specifier key]]; + if ([vc respondsToSelector:@selector(setDelegate:)]) { + [vc performSelector:@selector(setDelegate:) withObject:self.delegate]; + } + if ([vc respondsToSelector:@selector(setSettingsStore:)]) { + [vc performSelector:@selector(setSettingsStore:) withObject:self.settingsStore]; + } + self.navigationController.delegate = nil; + [self.navigationController pushViewController:vc animated:YES]; + [vc performSelector:@selector(release)]; + return; + } + + if (nil == [specifier file]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + return; + } + + IASKAppSettingsViewController *targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex] objectForKey:@"viewController"]; + + if (targetViewController == nil) { + // the view controller has not been created yet, create it and set it to our viewList array + // create a new dictionary with the new view controller + NSMutableDictionary *newItemDict = [NSMutableDictionary dictionaryWithCapacity:3]; + [newItemDict addEntriesFromDictionary: [self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex]]; // copy the title and explain strings + + targetViewController = [[[self class] alloc] initWithNibName:@"IASKAppSettingsView" bundle:nil]; + targetViewController.showDoneButton = NO; + targetViewController.settingsStore = self.settingsStore; + targetViewController.delegate = self.delegate; + + // add the new view controller to the dictionary and then to the 'viewList' array + [newItemDict setObject:targetViewController forKey:@"viewController"]; + [self.viewList replaceObjectAtIndex:kIASKSpecifierChildViewControllerIndex withObject:newItemDict]; + [targetViewController release]; + + // load the view controll back in to push it + targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex] objectForKey:@"viewController"]; + } + targetViewController.file = specifier.file; // changes settingsReader + targetViewController.settingsReader.delegate = self.settingsReader.delegate; + [targetViewController.settingsReader initWithFile:specifier.file]; + targetViewController.title = specifier.title; + targetViewController.showCreditsFooter = NO; + [[self navigationController] pushViewController:targetViewController animated:YES]; + } else if ([[specifier type] isEqualToString:kIASKOpenURLSpecifier]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:specifier.file]]; + } else if ([[specifier type] isEqualToString:kIASKButtonSpecifier]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if ([self.delegate respondsToSelector:@selector(settingsViewController:buttonTappedForKey:)]) { + [self.delegate settingsViewController:self buttonTappedForKey:[specifier key]]; + } else { + // legacy code, provided for backward compatibility + // the delegate mechanism above is much cleaner and doesn't leak + Class buttonClass = [specifier buttonClass]; + SEL buttonAction = [specifier buttonAction]; + if ([buttonClass respondsToSelector:buttonAction]) { + [buttonClass performSelector:buttonAction withObject:self withObject:[specifier key]]; + NSLog(@"InAppSettingsKit Warning: Using IASKButtonSpecifier without implementing the delegate method is deprecated"); + } + } + } else if ([[specifier type] isEqualToString:kIASKMailComposeSpecifier]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if ([MFMailComposeViewController canSendMail]) { + MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init]; + mailViewController.navigationBar.barStyle = self.navigationController.navigationBar.barStyle; + mailViewController.navigationBar.tintColor = self.navigationController.navigationBar.tintColor; + + if ([specifier localizedObjectForKey:kIASKMailComposeSubject]) { + [mailViewController setSubject:[specifier localizedObjectForKey:kIASKMailComposeSubject]]; + } + if ([[specifier specifierDict] objectForKey:kIASKMailComposeToRecipents]) { + [mailViewController setToRecipients:[[specifier specifierDict] objectForKey:kIASKMailComposeToRecipents]]; + } + if ([[specifier specifierDict] objectForKey:kIASKMailComposeCcRecipents]) { + [mailViewController setCcRecipients:[[specifier specifierDict] objectForKey:kIASKMailComposeCcRecipents]]; + } + if ([[specifier specifierDict] objectForKey:kIASKMailComposeBccRecipents]) { + [mailViewController setBccRecipients:[[specifier specifierDict] objectForKey:kIASKMailComposeBccRecipents]]; + } + if ([specifier localizedObjectForKey:kIASKMailComposeBody]) { + BOOL isHTML = NO; + if ([[specifier specifierDict] objectForKey:kIASKMailComposeBodyIsHTML]) { + isHTML = [[[specifier specifierDict] objectForKey:kIASKMailComposeBodyIsHTML] boolValue]; + } + + if ([self.delegate respondsToSelector:@selector(settingsViewController:mailComposeBodyForSpecifier:)]) { + [mailViewController setMessageBody:[self.delegate settingsViewController:self + mailComposeBodyForSpecifier:specifier] isHTML:isHTML]; + } + else { + [mailViewController setMessageBody:[specifier localizedObjectForKey:kIASKMailComposeBody] isHTML:isHTML]; + } + } + + UIViewController *vc = nil; + + if ([self.delegate respondsToSelector:@selector(settingsViewController:viewControllerForMailComposeViewForSpecifier:)]) { + vc = [self.delegate settingsViewController:self viewControllerForMailComposeViewForSpecifier:specifier]; + } + + if (vc == nil) { + vc = self; + } + + mailViewController.mailComposeDelegate = vc; + [vc presentModalViewController:mailViewController animated:YES]; + [mailViewController release]; + } else { + UIAlertView *alert = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Mail not configured", @"InAppSettingsKit") + message:NSLocalizedString(@"This device is not configured for sending Email. Please configure the Mail settings in the Settings app.", @"InAppSettingsKit") + delegate: nil + cancelButtonTitle:NSLocalizedString(@"OK", @"InAppSettingsKit") + otherButtonTitles:nil]; + [alert show]; + [alert release]; + } + + } else if ([[specifier type] isEqualToString:kIASKCustomViewSpecifier] && [self.delegate respondsToSelector:@selector(settingsViewController:tableView:didSelectCustomViewSpecifier:)]) { + [self.delegate settingsViewController:self tableView:tableView didSelectCustomViewSpecifier:specifier]; + } else { + [tableView deselectRowAtIndexPath:indexPath animated:NO]; + } +} + + +#pragma mark - +#pragma mark MFMailComposeViewControllerDelegate Function + +-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { + + // Forward the mail compose delegate + if ([self.delegate respondsToSelector:@selector(settingsViewController:mailComposeController:didFinishWithResult:error:)]) { + [self.delegate settingsViewController:self + mailComposeController:controller + didFinishWithResult:result + error:error]; + } + + // NOTE: No error handling is done here + [self dismissModalViewControllerAnimated:YES]; +} + +#pragma mark - +#pragma mark UITextFieldDelegate Functions + +- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { + self.currentFirstResponder = textField; + return YES; +} + +- (void)_textChanged:(id)sender { + IASKTextField *text = (IASKTextField*)sender; + [_settingsStore setObject:[text text] forKey:[text key]]; + [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged + object:[text key] + userInfo:[NSDictionary dictionaryWithObject:[text text] + forKey:[text key]]]; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField{ + [textField resignFirstResponder]; + self.currentFirstResponder = nil; + return YES; +} + + +#pragma mark Notifications + +- (void)synchronizeSettings { + [_settingsStore synchronize]; +} + +static NSDictionary *oldUserDefaults = nil; +- (void)userDefaultsDidChange { + NSDictionary *currentDict = [NSUserDefaults standardUserDefaults].dictionaryRepresentation; + NSMutableArray *indexPathsToUpdate = [NSMutableArray array]; + for (NSString *key in currentDict.allKeys) { + if (![[oldUserDefaults valueForKey:key] isEqual:[currentDict valueForKey:key]]) { + NSIndexPath *path = [self.settingsReader indexPathForKey:key]; + if (path && ![[self.settingsReader specifierForKey:key].type isEqualToString:kIASKCustomViewSpecifier]) { + [indexPathsToUpdate addObject:path]; + } + } + } + [oldUserDefaults release], oldUserDefaults = [currentDict retain]; + + + for (UITableViewCell *cell in self.tableView.visibleCells) { + if ([cell isKindOfClass:[IASKPSTextFieldSpecifierViewCell class]] && [((IASKPSTextFieldSpecifierViewCell*)cell).textField isFirstResponder]) { + [indexPathsToUpdate removeObject:[self.tableView indexPathForCell:cell]]; + } + } + if (indexPathsToUpdate.count) { + [self.tableView reloadRowsAtIndexPaths:indexPathsToUpdate withRowAnimation:UITableViewRowAnimationNone]; + } +} + +- (void)reload { + // wait 0.5 sec until UI is available after applicationWillEnterForeground + [self.tableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.5]; +} + +#pragma mark CGRect Utility function +CGRect IASKCGRectSwap(CGRect rect) { + CGRect newRect; + newRect.origin.x = rect.origin.y; + newRect.origin.y = rect.origin.x; + newRect.size.width = rect.size.height; + newRect.size.height = rect.size.width; + return newRect; +} +@end diff --git a/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h b/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h new file mode 100644 index 000000000..08b6ceb27 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h @@ -0,0 +1,30 @@ +// +// IASKAppSettingsWebViewController.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import + +@interface IASKAppSettingsWebViewController : UIViewController { + UIWebView *webView; + NSURL *url; +} + +- (id)initWithFile:(NSString*)htmlFileName key:(NSString*)key; + +@property (nonatomic, retain) IBOutlet UIWebView *webView; +@property (nonatomic, retain) NSURL *url; + +@end diff --git a/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m b/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m new file mode 100644 index 000000000..46429b3ce --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m @@ -0,0 +1,148 @@ +// +// IASKAppSettingsWebViewController.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKAppSettingsWebViewController.h" + +@implementation IASKAppSettingsWebViewController + +@synthesize url; +@synthesize webView; + +- (id)initWithFile:(NSString*)urlString key:(NSString*)key { + if (!(self = [super initWithNibName:nil bundle:nil])) { + return nil; + } + + self.url = [NSURL URLWithString:urlString]; + if (!self.url || ![self.url scheme]) { + NSString *path = [[NSBundle mainBundle] pathForResource:[urlString stringByDeletingPathExtension] ofType:[urlString pathExtension]]; + if(path) + self.url = [NSURL fileURLWithPath:path]; + else + self.url = nil; + } + return self; +} + + +- (void)dealloc { + [webView release], webView = nil; + [url release], url = nil; + + [super dealloc]; +} + +- (void)viewWillAppear:(BOOL)animated { + [webView loadRequest:[NSURLRequest requestWithURL:self.url]]; +} + +- (void)viewDidUnload { + [super viewDidUnload]; + self.webView = nil; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return YES; +} + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + self.navigationItem.title = [self.webView stringByEvaluatingJavaScriptFromString:@"document.title"]; +} + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { + NSURL *newURL = [request URL]; + + // intercept mailto URL and send it to an in-app Mail compose view instead + if ([[newURL scheme] isEqualToString:@"mailto"]) { + + NSArray *rawURLparts = [[newURL resourceSpecifier] componentsSeparatedByString:@"?"]; + if (rawURLparts.count > 2) { + return NO; // invalid URL + } + + MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init]; + mailViewController.mailComposeDelegate = self; + + NSMutableArray *toRecipients = [NSMutableArray array]; + NSString *defaultRecipient = [rawURLparts objectAtIndex:0]; + if (defaultRecipient.length) { + [toRecipients addObject:defaultRecipient]; + } + + if (rawURLparts.count == 2) { + NSString *queryString = [rawURLparts objectAtIndex:1]; + + NSArray *params = [queryString componentsSeparatedByString:@"&"]; + for (NSString *param in params) { + NSArray *keyValue = [param componentsSeparatedByString:@"="]; + if (keyValue.count != 2) { + continue; + } + NSString *key = [[keyValue objectAtIndex:0] lowercaseString]; + NSString *value = [keyValue objectAtIndex:1]; + + value = (NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, + (CFStringRef)value, + CFSTR(""), + kCFStringEncodingUTF8); + [value autorelease]; + + if ([key isEqualToString:@"subject"]) { + [mailViewController setSubject:value]; + } + + if ([key isEqualToString:@"body"]) { + [mailViewController setMessageBody:value isHTML:NO]; + } + + if ([key isEqualToString:@"to"]) { + [toRecipients addObjectsFromArray:[value componentsSeparatedByString:@","]]; + } + + if ([key isEqualToString:@"cc"]) { + NSArray *recipients = [value componentsSeparatedByString:@","]; + [mailViewController setCcRecipients:recipients]; + } + + if ([key isEqualToString:@"bcc"]) { + NSArray *recipients = [value componentsSeparatedByString:@","]; + [mailViewController setBccRecipients:recipients]; + } + } + } + + [mailViewController setToRecipients:toRecipients]; + + [self presentModalViewController:mailViewController animated:YES]; + [mailViewController release]; + return NO; + } + + // open inline if host is the same, otherwise, pass to the system + if (![newURL host] || [[newURL host] isEqualToString:[self.url host]]) { + return YES; + } + [[UIApplication sharedApplication] openURL:newURL]; + return NO; +} + +- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { + [self dismissModalViewControllerAnimated:YES]; +} + + + +@end diff --git a/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h b/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h new file mode 100644 index 000000000..d2810d368 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h @@ -0,0 +1,36 @@ +// +// IASKSpecifierValuesViewController.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import "IASKSettingsStore.h" +#import "IASKViewController.h" +@class IASKSpecifier; +@class IASKSettingsReader; + +@interface IASKSpecifierValuesViewController : UIViewController { + UITableView *_tableView; + + IASKSpecifier *_currentSpecifier; + NSIndexPath *_checkedItem; + IASKSettingsReader *_settingsReader; + id _settingsStore; +} + +@property (nonatomic, retain) IBOutlet UITableView *tableView; +@property (nonatomic, retain) NSIndexPath *checkedItem; +@property (nonatomic, retain) IASKSpecifier *currentSpecifier; + +@end diff --git a/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m b/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m new file mode 100644 index 000000000..84236a755 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m @@ -0,0 +1,195 @@ +// +// IASKSpecifierValuesViewController.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSpecifierValuesViewController.h" +#import "IASKSpecifier.h" +#import "IASKSettingsReader.h" +#import "IASKSettingsStoreUserDefaults.h" + +#define kCellValue @"kCellValue" + +@interface IASKSpecifierValuesViewController() +- (void)userDefaultsDidChange; +@end + +@implementation IASKSpecifierValuesViewController + +@synthesize tableView=_tableView; +@synthesize currentSpecifier=_currentSpecifier; +@synthesize checkedItem=_checkedItem; +@synthesize settingsReader = _settingsReader; +@synthesize settingsStore = _settingsStore; + +- (void) updateCheckedItem { + NSInteger index; + + // Find the currently checked item + if([self.settingsStore objectForKey:[_currentSpecifier key]]) { + index = [[_currentSpecifier multipleValues] indexOfObject:[self.settingsStore objectForKey:[_currentSpecifier key]]]; + } else { + index = [[_currentSpecifier multipleValues] indexOfObject:[_currentSpecifier defaultValue]]; + } + [self setCheckedItem:[NSIndexPath indexPathForRow:index inSection:0]]; +} + +- (id)settingsStore { + if(_settingsStore == nil) { + _settingsStore = [[IASKSettingsStoreUserDefaults alloc] init]; + } + return _settingsStore; +} + +- (void)viewWillAppear:(BOOL)animated { + if (_currentSpecifier) { + [self setTitle:[_currentSpecifier title]]; + [self updateCheckedItem]; + } + + if (_tableView) { + [_tableView reloadData]; + + // Make sure the currently checked item is visible + [_tableView scrollToRowAtIndexPath:[self checkedItem] atScrollPosition:UITableViewScrollPositionMiddle animated:NO]; + } + [super viewWillAppear:animated]; +} + +- (void)viewDidAppear:(BOOL)animated { + [_tableView flashScrollIndicators]; + [super viewDidAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(userDefaultsDidChange) + name:NSUserDefaultsDidChangeNotification + object:[NSUserDefaults standardUserDefaults]]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUserDefaultsDidChangeNotification object:nil]; + [super viewDidDisappear:animated]; +} + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return YES; +} + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload { + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; + self.tableView = nil; +} + + +- (void)dealloc { + [_currentSpecifier release], _currentSpecifier = nil; + [_checkedItem release], _checkedItem = nil; + [_settingsReader release], _settingsReader = nil; + [_settingsStore release], _settingsStore = nil; + [_tableView release], _tableView = nil; + [super dealloc]; +} + + +#pragma mark - +#pragma mark UITableView delegates + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [_currentSpecifier multipleValuesCount]; +} + +- (void)selectCell:(UITableViewCell *)cell { + [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; + [[cell textLabel] setTextColor:kIASKgrayBlueColor]; +} + +- (void)deselectCell:(UITableViewCell *)cell { + [cell setAccessoryType:UITableViewCellAccessoryNone]; + [[cell textLabel] setTextColor:[UIColor darkTextColor]]; +} + +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { + return [_currentSpecifier footerText]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellValue]; + NSArray *titles = [_currentSpecifier multipleTitles]; + + if (!cell) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellValue] autorelease]; + } + + if ([indexPath isEqual:[self checkedItem]]) { + [self selectCell:cell]; + } else { + [self deselectCell:cell]; + } + + @try { + [[cell textLabel] setText:[self.settingsReader titleForStringId:[titles objectAtIndex:indexPath.row]]]; + } + @catch (NSException * e) {} + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + + if (indexPath == [self checkedItem]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + return; + } + + NSArray *values = [_currentSpecifier multipleValues]; + + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + [self deselectCell:[tableView cellForRowAtIndexPath:[self checkedItem]]]; + [self selectCell:[tableView cellForRowAtIndexPath:indexPath]]; + [self setCheckedItem:indexPath]; + + [self.settingsStore setObject:[values objectAtIndex:indexPath.row] forKey:[_currentSpecifier key]]; + [self.settingsStore synchronize]; + [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged + object:[_currentSpecifier key] + userInfo:[NSDictionary dictionaryWithObject:[values objectAtIndex:indexPath.row] + forKey:[_currentSpecifier key]]]; +} + +#pragma mark Notifications + +- (void)userDefaultsDidChange { + NSIndexPath *oldCheckedItem = [[self.checkedItem retain] autorelease]; + if(_currentSpecifier) { + [self updateCheckedItem]; + } + + // only reload the table if it had changed; prevents animation cancellation + if (![self.checkedItem isEqual:oldCheckedItem]) { + [_tableView reloadData]; + } +} + +@end diff --git a/InAppSettingsKit/Controllers/IASKViewController.h b/InAppSettingsKit/Controllers/IASKViewController.h new file mode 100644 index 000000000..40e450415 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKViewController.h @@ -0,0 +1,26 @@ +// +// IASKAppSettingsViewController.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +@class IASKSettingsReader; +@protocol IASKSettingsStore; + +// protocol all IASK view controllers implement +@protocol IASKViewController + +@property (nonatomic, retain) IASKSettingsReader* settingsReader; +@property (nonatomic, retain) id settingsStore; + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsReader.h b/InAppSettingsKit/Models/IASKSettingsReader.h new file mode 100644 index 000000000..bbdd1a5b5 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsReader.h @@ -0,0 +1,149 @@ +// +// IASKSettingsReader.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + +#define kIASKPreferenceSpecifiers @"PreferenceSpecifiers" +#define kIASKType @"Type" +#define kIASKTitle @"Title" +#define kIASKFooterText @"FooterText" +#define kIASKKey @"Key" +#define kIASKFile @"File" +#define kIASKDefaultValue @"DefaultValue" +#define kIASKMinimumValue @"MinimumValue" +#define kIASKMaximumValue @"MaximumValue" +#define kIASKTrueValue @"TrueValue" +#define kIASKFalseValue @"FalseValue" +#define kIASKIsSecure @"IsSecure" +#define KIASKKeyboardType @"KeyboardType" +#define kIASKAutocapitalizationType @"AutocapitalizationType" +#define kIASKAutoCorrectionType @"AutocorrectionType" +#define kIASKValues @"Values" +#define kIASKTitles @"Titles" +#define kIASKViewControllerClass @"IASKViewControllerClass" +#define kIASKViewControllerSelector @"IASKViewControllerSelector" +#define kIASKButtonClass @"IASKButtonClass" +#define kIASKButtonAction @"IASKButtonAction" +#define kIASKMailComposeToRecipents @"IASKMailComposeToRecipents" +#define kIASKMailComposeCcRecipents @"IASKMailComposeCcRecipents" +#define kIASKMailComposeBccRecipents @"IASKMailComposeBccRecipents" +#define kIASKMailComposeSubject @"IASKMailComposeSubject" +#define kIASKMailComposeBody @"IASKMailComposeBody" +#define kIASKMailComposeBodyIsHTML @"IASKMailComposeBodyIsHTML" +#define kIASKKeyboardAlphabet @"Alphabet" +#define kIASKKeyboardNumbersAndPunctuation @"NumbersAndPunctuation" +#define kIASKKeyboardNumberPad @"NumberPad" +#define kIASKKeyboardDecimalPad @"DecimalPad" + +#define KIASKKeyboardURL @"URL" +#define kIASKKeyboardEmailAddress @"EmailAddress" +#define kIASKAutoCapNone @"None" +#define kIASKAutoCapSentences @"Sentences" +#define kIASKAutoCapWords @"Words" +#define kIASKAutoCapAllCharacters @"AllCharacters" +#define kIASKAutoCorrDefault @"Default" +#define kIASKAutoCorrNo @"No" +#define kIASKAutoCorrYes @"Yes" +#define kIASKMinimumValueImage @"MinimumValueImage" +#define kIASKMaximumValueImage @"MaximumValueImage" + +#define kIASKPSGroupSpecifier @"PSGroupSpecifier" +#define kIASKPSToggleSwitchSpecifier @"PSToggleSwitchSpecifier" +#define kIASKPSMultiValueSpecifier @"PSMultiValueSpecifier" +#define kIASKPSSliderSpecifier @"PSSliderSpecifier" +#define kIASKPSTitleValueSpecifier @"PSTitleValueSpecifier" +#define kIASKPSTextFieldSpecifier @"PSTextFieldSpecifier" +#define kIASKPSChildPaneSpecifier @"PSChildPaneSpecifier" +#define kIASKOpenURLSpecifier @"IASKOpenURLSpecifier" +#define kIASKButtonSpecifier @"IASKButtonSpecifier" +#define kIASKMailComposeSpecifier @"IASKMailComposeSpecifier" +#define kIASKCustomViewSpecifier @"IASKCustomViewSpecifier" + +#define kIASKBundleFolder @"Settings.bundle" +#define kIASKBundleFolderAlt @"InAppSettings.bundle" +#define kIASKBundleFilename @"Root.plist" +#define KIASKBundleLocaleFolderExtension @".lproj" + +#define kIASKAppSettingChanged @"kAppSettingChanged" + +#define kIASKSectionHeaderIndex 0 + +#define kIASKSliderNoImagesPadding 11 +#define kIASKSliderImagesPadding 43 + + +#define kIASKTableWidth 320 +#define kIASKSpacing 5 +#define kIASKMinLabelWidth 97 +#define kIASKMinValueWidth 35 +#define kIASKPaddingLeft 9 +#define kIASKPaddingRight 10 +#define kIASKHorizontalPaddingGroupTitles 19 +#define kIASKVerticalPaddingGroupTitles 15 + +#define kIASKLabelFontSize 17 +#define kIASKgrayBlueColor [UIColor colorWithRed:0.318 green:0.4 blue:0.569 alpha:1.0] + +#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_4_0 +#define kCFCoreFoundationVersionNumber_iPhoneOS_4_0 550.32 +#endif + +#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_4_1 +#define kCFCoreFoundationVersionNumber_iPhoneOS_4_1 550.38 +#endif + + +#define IASK_IF_IOS4_OR_GREATER(...) \ +if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_4_0) \ +{ \ +__VA_ARGS__ \ +} + +@class IASKSpecifier; + +@protocol IASKSettingsReaderFilterDelegate +- (NSDictionary*) filterPreferenceSpecifier:(NSDictionary*)specifier; +@end + +@interface IASKSettingsReader : NSObject { + NSString *_path; + NSString *_localizationTable; + NSString *_bundlePath; + NSDictionary *_settingsBundle; + NSArray *_dataSource; + NSBundle *_bundle; + id delegate; +} + +- (id)initWithFile:(NSString*)file; +- (NSInteger)numberOfSections; +- (NSInteger)numberOfRowsForSection:(NSInteger)section; +- (IASKSpecifier*)specifierForIndexPath:(NSIndexPath*)indexPath; +- (NSIndexPath*)indexPathForKey:(NSString*)key; +- (IASKSpecifier*)specifierForKey:(NSString*)key; +- (NSString*)titleForSection:(NSInteger)section; +- (NSString*)keyForSection:(NSInteger)section; +- (NSString*)footerTextForSection:(NSInteger)section; +- (NSString*)titleForStringId:(NSString*)stringId; +- (NSString*)pathForImageNamed:(NSString*)image; + +@property (nonatomic, retain) NSString *path; +@property (nonatomic, retain) NSString *localizationTable; +@property (nonatomic, retain) NSString *bundlePath; +@property (nonatomic, retain) NSDictionary *settingsBundle; +@property (nonatomic, retain) NSArray *dataSource; +@property (nonatomic, retain) id delegate; +@end diff --git a/InAppSettingsKit/Models/IASKSettingsReader.m b/InAppSettingsKit/Models/IASKSettingsReader.m new file mode 100644 index 000000000..dd82ce72b --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsReader.m @@ -0,0 +1,278 @@ +// +// IASKSettingsReader.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSettingsReader.h" +#import "IASKSpecifier.h" + +@interface IASKSettingsReader (private) +- (void)_reinterpretBundle:(NSDictionary*)settingsBundle; +- (BOOL)_sectionHasHeading:(NSInteger)section; +- (NSString *)platformSuffix; +- (NSString *)locateSettingsFile:(NSString *)file; + +@end + +@implementation IASKSettingsReader + +@synthesize path=_path, +localizationTable=_localizationTable, +bundlePath=_bundlePath, +settingsBundle=_settingsBundle, +dataSource=_dataSource; +@synthesize delegate; + +- (id)init { + return [self initWithFile:@"Root"]; +} + +- (id)initWithFile:(NSString*)file { + if ((self=[super init])) { + + + self.path = [self locateSettingsFile: file]; + [self setSettingsBundle:[NSDictionary dictionaryWithContentsOfFile:self.path]]; + self.bundlePath = [self.path stringByDeletingLastPathComponent]; + _bundle = [[NSBundle bundleWithPath:[self bundlePath]] retain]; + + // Look for localization file + self.localizationTable = [self.settingsBundle objectForKey:@"StringsTable"]; + if (!self.localizationTable) + { + // Look for localization file using filename + self.localizationTable = [[[[self.path stringByDeletingPathExtension] // removes '.plist' + stringByDeletingPathExtension] // removes potential '.inApp' + lastPathComponent] // strip absolute path + stringByReplacingOccurrencesOfString:[self platformSuffix] withString:@""]; // removes potential '~device' (~ipad, ~iphone) + if([_bundle pathForResource:self.localizationTable ofType:@"strings"] == nil){ + // Could not find the specified localization: use default + self.localizationTable = @"Root"; + } + } + + if (_settingsBundle) { + [self _reinterpretBundle:_settingsBundle]; + } + } + return self; +} + +- (void)dealloc { + [_path release], _path = nil; + [_localizationTable release], _localizationTable = nil; + [_bundlePath release], _bundlePath = nil; + [_settingsBundle release], _settingsBundle = nil; + [_dataSource release], _dataSource = nil; + [_bundle release], _bundle = nil; + + [super dealloc]; +} + +- (void)_reinterpretBundle:(NSDictionary*)settingsBundle { + NSArray *preferenceSpecifiers = [settingsBundle objectForKey:kIASKPreferenceSpecifiers]; + NSInteger sectionCount = -1; + NSMutableArray *dataSource = [[[NSMutableArray alloc] init] autorelease]; + + for (NSDictionary *specifier in preferenceSpecifiers) { + if (delegate != nil) { + specifier = [delegate filterPreferenceSpecifier:specifier]; + if (specifier == nil) { + // skip + continue; + } + } + if ([(NSString*)[specifier objectForKey:kIASKType] isEqualToString:kIASKPSGroupSpecifier]) { + NSMutableArray *newArray = [[NSMutableArray alloc] init]; + + [newArray addObject:specifier]; + [dataSource addObject:newArray]; + [newArray release]; + sectionCount++; + } + else { + if (sectionCount == -1) { + NSMutableArray *newArray = [[NSMutableArray alloc] init]; + [dataSource addObject:newArray]; + [newArray release]; + sectionCount++; + } + + IASKSpecifier *newSpecifier = [[IASKSpecifier alloc] initWithSpecifier:specifier]; + [(NSMutableArray*)[dataSource objectAtIndex:sectionCount] addObject:newSpecifier]; + [newSpecifier release]; + } + } + [self setDataSource:dataSource]; +} + +- (BOOL)_sectionHasHeading:(NSInteger)section { + return [[[[self dataSource] objectAtIndex:section] objectAtIndex:0] isKindOfClass:[NSDictionary class]]; +} + +- (NSInteger)numberOfSections { + return [[self dataSource] count]; +} + +- (NSInteger)numberOfRowsForSection:(NSInteger)section { + int headingCorrection = [self _sectionHasHeading:section] ? 1 : 0; + return [(NSArray*)[[self dataSource] objectAtIndex:section] count] - headingCorrection; +} + +- (IASKSpecifier*)specifierForIndexPath:(NSIndexPath*)indexPath { + int headingCorrection = [self _sectionHasHeading:indexPath.section] ? 1 : 0; + + IASKSpecifier *specifier = [[[self dataSource] objectAtIndex:indexPath.section] objectAtIndex:(indexPath.row+headingCorrection)]; + specifier.settingsReader = self; + return specifier; +} + +- (NSIndexPath*)indexPathForKey:(NSString *)key { + for (NSUInteger sectionIndex = 0; sectionIndex < self.dataSource.count; sectionIndex++) { + NSArray *section = [self.dataSource objectAtIndex:sectionIndex]; + for (NSUInteger rowIndex = 0; rowIndex < section.count; rowIndex++) { + IASKSpecifier *specifier = (IASKSpecifier*)[section objectAtIndex:rowIndex]; + if ([specifier isKindOfClass:[IASKSpecifier class]] && [specifier.key isEqualToString:key]) { + NSUInteger correctedRowIndex = rowIndex - [self _sectionHasHeading:sectionIndex]; + return [NSIndexPath indexPathForRow:correctedRowIndex inSection:sectionIndex]; + } + } + } + return nil; +} + +- (IASKSpecifier*)specifierForKey:(NSString*)key { + for (NSArray *specifiers in _dataSource) { + for (id sp in specifiers) { + if ([sp isKindOfClass:[IASKSpecifier class]]) { + if ([[sp key] isEqualToString:key]) { + return sp; + } + } + } + } + return nil; +} + +- (NSString*)titleForSection:(NSInteger)section { + if ([self _sectionHasHeading:section]) { + NSDictionary *dict = [[[self dataSource] objectAtIndex:section] objectAtIndex:kIASKSectionHeaderIndex]; + return [self titleForStringId:[dict objectForKey:kIASKTitle]]; + } + return nil; +} + +- (NSString*)keyForSection:(NSInteger)section { + if ([self _sectionHasHeading:section]) { + return [[[[self dataSource] objectAtIndex:section] objectAtIndex:kIASKSectionHeaderIndex] objectForKey:kIASKKey]; + } + return nil; +} + +- (NSString*)footerTextForSection:(NSInteger)section { + if ([self _sectionHasHeading:section]) { + NSDictionary *dict = [[[self dataSource] objectAtIndex:section] objectAtIndex:kIASKSectionHeaderIndex]; + return [self titleForStringId:[dict objectForKey:kIASKFooterText]]; + } + return nil; +} + +- (NSString*)titleForStringId:(NSString*)stringId { + return [_bundle localizedStringForKey:stringId value:stringId table:self.localizationTable]; +} + +- (NSString*)pathForImageNamed:(NSString*)image { + return [[self bundlePath] stringByAppendingPathComponent:image]; +} + +- (NSString *)platformSuffix { + BOOL isPad = NO; +#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200) + isPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; +#endif + return isPad ? @"~ipad" : @"~iphone"; +} + +- (NSString *)file:(NSString *)file + withBundle:(NSString *)bundle + suffix:(NSString *)suffix + extension:(NSString *)extension { + + NSString *appBundle = [[NSBundle mainBundle] bundlePath]; + bundle = [appBundle stringByAppendingPathComponent:bundle]; + file = [file stringByAppendingFormat:@"%@%@", suffix, extension]; + return [bundle stringByAppendingPathComponent:file]; + +} + +- (NSString *)locateSettingsFile: (NSString *)file { + + // The file is searched in the following order: + // + // InAppSettings.bundle/FILE~DEVICE.inApp.plist + // InAppSettings.bundle/FILE.inApp.plist + // InAppSettings.bundle/FILE~DEVICE.plist + // InAppSettings.bundle/FILE.plist + // Settings.bundle/FILE~DEVICE.inApp.plist + // Settings.bundle/FILE.inApp.plist + // Settings.bundle/FILE~DEVICE.plist + // Settings.bundle/FILE.plist + // + // where DEVICE is either "iphone" or "ipad" depending on the current + // interface idiom. + // + // Settings.app uses the ~DEVICE suffixes since iOS 4.0. There are some + // differences from this implementation: + // - For an iPhone-only app running on iPad, Settings.app will not use the + // ~iphone suffix. There is no point in using these suffixes outside + // of universal apps anyway. + // - This implementation uses the device suffixes on iOS 3.x as well. + // - also check current locale (short only) + + NSArray *bundles = + [NSArray arrayWithObjects:kIASKBundleFolderAlt, kIASKBundleFolder, nil]; + + NSArray *extensions = + [NSArray arrayWithObjects:@".inApp.plist", @".plist", nil]; + + NSArray *suffixes = + [NSArray arrayWithObjects:[self platformSuffix], @"", nil]; + + NSArray *languages = + [NSArray arrayWithObjects:[[[NSLocale preferredLanguages] objectAtIndex:0] stringByAppendingString:KIASKBundleLocaleFolderExtension], @"", nil]; + + NSString *path = nil; + NSFileManager *fileManager = [NSFileManager defaultManager]; + + for (NSString *bundle in bundles) { + for (NSString *extension in extensions) { + for (NSString *suffix in suffixes) { + for (NSString *language in languages) { + path = [self file:file + withBundle:[bundle stringByAppendingPathComponent:language] + suffix:suffix + extension:extension]; + if ([fileManager fileExistsAtPath:path]) { + goto exitFromNestedLoop; + } + } + } + } + } + +exitFromNestedLoop: + return path; +} + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsStore.h b/InAppSettingsKit/Models/IASKSettingsStore.h new file mode 100644 index 000000000..c1b53ba2b --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStore.h @@ -0,0 +1,39 @@ +// +// IASKSettingsStore.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + +@protocol IASKSettingsStore +@required +- (void)setBool:(BOOL)value forKey:(NSString*)key; +- (void)setFloat:(float)value forKey:(NSString*)key; +- (void)setDouble:(double)value forKey:(NSString*)key; +- (void)setInteger:(int)value forKey:(NSString*)key; +- (void)setObject:(id)value forKey:(NSString*)key; +- (BOOL)boolForKey:(NSString*)key; +- (float)floatForKey:(NSString*)key; +- (double)doubleForKey:(NSString*)key; +- (int)integerForKey:(NSString*)key; +- (id)objectForKey:(NSString*)key; +- (BOOL)synchronize; // Write settings to a permanant storage. Returns YES on success, NO otherwise +@end + + +@interface IASKAbstractSettingsStore : NSObject { +} + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsStore.m b/InAppSettingsKit/Models/IASKSettingsStore.m new file mode 100644 index 000000000..8efbe7da2 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStore.m @@ -0,0 +1,68 @@ +// +// IASKSettingsStore.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSettingsStore.h" + +@implementation IASKAbstractSettingsStore + +- (void)setObject:(id)value forKey:(NSString*)key { + [NSException raise:@"Unimplemented" + format:@"setObject:forKey: must be implemented in subclasses of IASKAbstractSettingsStore"]; +} + +- (id)objectForKey:(NSString*)key { + [NSException raise:@"Unimplemented" + format:@"objectForKey: must be implemented in subclasses of IASKAbstractSettingsStore"]; + return nil; +} + +- (void)setBool:(BOOL)value forKey:(NSString*)key { + [self setObject:[NSNumber numberWithBool:value] forKey:key]; +} + +- (void)setFloat:(float)value forKey:(NSString*)key { + [self setObject:[NSNumber numberWithFloat:value] forKey:key]; +} + +- (void)setInteger:(int)value forKey:(NSString*)key { + [self setObject:[NSNumber numberWithInt:value] forKey:key]; +} + +- (void)setDouble:(double)value forKey:(NSString*)key { + [self setObject:[NSNumber numberWithDouble:value] forKey:key]; +} + +- (BOOL)boolForKey:(NSString*)key { + return [[self objectForKey:key] boolValue]; +} + +- (float)floatForKey:(NSString*)key { + return [[self objectForKey:key] floatValue]; +} +- (int)integerForKey:(NSString*)key { + return [[self objectForKey:key] intValue]; +} + +- (double)doubleForKey:(NSString*)key { + return [[self objectForKey:key] doubleValue]; +} + +- (BOOL)synchronize { + return NO; +} + +@end \ No newline at end of file diff --git a/InAppSettingsKit/Models/IASKSettingsStoreFile.h b/InAppSettingsKit/Models/IASKSettingsStoreFile.h new file mode 100644 index 000000000..6d4fe2993 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStoreFile.h @@ -0,0 +1,28 @@ +// +// IASKSettingsStoreFile.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import "IASKSettingsStore.h" + +@interface IASKSettingsStoreFile : IASKAbstractSettingsStore { + NSString * _filePath; + NSMutableDictionary * _dict; +} + +- (id)initWithPath:(NSString*)path; + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsStoreFile.m b/InAppSettingsKit/Models/IASKSettingsStoreFile.m new file mode 100644 index 000000000..104642d7e --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStoreFile.m @@ -0,0 +1,54 @@ +// +// IASKSettingsStoreFile.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSettingsStoreFile.h" + + +@implementation IASKSettingsStoreFile + +- (id)initWithPath:(NSString*)path { + if((self = [super init])) { + _filePath = [path retain]; + _dict = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; + if(_dict == nil) { + _dict = [[NSMutableDictionary alloc] init]; + } + } + return self; +} + +- (void)dealloc { + [_dict release], _dict = nil; + [_filePath release], _filePath = nil; + + [super dealloc]; +} + + +- (void)setObject:(id)value forKey:(NSString *)key { + [_dict setObject:value forKey:key]; +} + +- (id)objectForKey:(NSString *)key { + return [_dict objectForKey:key]; +} + +- (BOOL)synchronize { + return [_dict writeToFile:_filePath atomically:YES]; +} + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.h b/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.h new file mode 100644 index 000000000..3731f5e3b --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.h @@ -0,0 +1,25 @@ +// +// IASKSettingsStoreUserDefaults.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import "IASKSettingsStore.h" + +@interface IASKSettingsStoreUserDefaults : IASKAbstractSettingsStore { + +} + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.m b/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.m new file mode 100644 index 000000000..fd24bf097 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.m @@ -0,0 +1,67 @@ +// +// IASKSettingsStoreUserDefaults.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSettingsStoreUserDefaults.h" + + +@implementation IASKSettingsStoreUserDefaults + +- (void)setBool:(BOOL)value forKey:(NSString*)key { + [[NSUserDefaults standardUserDefaults] setBool:value forKey:key]; +} + +- (void)setFloat:(float)value forKey:(NSString*)key { + [[NSUserDefaults standardUserDefaults] setFloat:value forKey:key]; +} + +- (void)setDouble:(double)value forKey:(NSString*)key { + [[NSUserDefaults standardUserDefaults] setDouble:value forKey:key]; +} + +- (void)setInteger:(int)value forKey:(NSString*)key { + [[NSUserDefaults standardUserDefaults] setInteger:value forKey:key]; +} + +- (void)setObject:(id)value forKey:(NSString*)key { + [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]; +} + +- (BOOL)boolForKey:(NSString*)key { + return [[NSUserDefaults standardUserDefaults] boolForKey:key]; +} + +- (float)floatForKey:(NSString*)key { + return [[NSUserDefaults standardUserDefaults] floatForKey:key]; +} + +- (double)doubleForKey:(NSString*)key { + return [[NSUserDefaults standardUserDefaults] doubleForKey:key]; +} + +- (int)integerForKey:(NSString*)key { + return [[NSUserDefaults standardUserDefaults] integerForKey:key]; +} + +- (id)objectForKey:(NSString*)key { + return [[NSUserDefaults standardUserDefaults] objectForKey:key]; +} + +- (BOOL)synchronize { + return [[NSUserDefaults standardUserDefaults] synchronize]; +} + +@end diff --git a/InAppSettingsKit/Models/IASKSpecifier.h b/InAppSettingsKit/Models/IASKSpecifier.h new file mode 100644 index 000000000..1e47d1ec8 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSpecifier.h @@ -0,0 +1,59 @@ +// +// IASKSpecifier.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import + +@class IASKSettingsReader; + +@interface IASKSpecifier : NSObject { + NSDictionary *_specifierDict; + NSDictionary *_multipleValuesDict; + IASKSettingsReader *_settingsReader; +} +@property (nonatomic, retain) NSDictionary *specifierDict; +@property (nonatomic, assign) IASKSettingsReader *settingsReader; + +- (id)initWithSpecifier:(NSDictionary*)specifier; +- (NSString*)localizedObjectForKey:(NSString*)key; +- (NSString*)title; +- (NSString*)key; +- (NSString*)type; +- (NSString*)titleForCurrentValue:(id)currentValue; +- (NSInteger)multipleValuesCount; +- (NSArray*)multipleValues; +- (NSArray*)multipleTitles; +- (NSString*)file; +- (id)defaultValue; +- (id)defaultStringValue; +- (BOOL)defaultBoolValue; +- (id)trueValue; +- (id)falseValue; +- (float)minimumValue; +- (float)maximumValue; +- (NSString*)minimumValueImage; +- (NSString*)maximumValueImage; +- (BOOL)isSecure; +- (UIKeyboardType)keyboardType; +- (UITextAutocapitalizationType)autocapitalizationType; +- (UITextAutocorrectionType)autoCorrectionType; +- (NSString*)footerText; +- (Class)viewControllerClass; +- (SEL)viewControllerSelector; +-(Class)buttonClass; +-(SEL)buttonAction; + +@end diff --git a/InAppSettingsKit/Models/IASKSpecifier.m b/InAppSettingsKit/Models/IASKSpecifier.m new file mode 100644 index 000000000..ebb38ac01 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSpecifier.m @@ -0,0 +1,240 @@ +// +// IASKSpecifier.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSpecifier.h" +#import "IASKSettingsReader.h" + +@interface IASKSpecifier () +@property (nonatomic, retain) NSDictionary *multipleValuesDict; +- (void)_reinterpretValues:(NSDictionary*)specifierDict; +@end + +@implementation IASKSpecifier + +@synthesize specifierDict=_specifierDict; +@synthesize multipleValuesDict=_multipleValuesDict; +@synthesize settingsReader = _settingsReader; + +- (id)initWithSpecifier:(NSDictionary*)specifier { + if ((self = [super init])) { + [self setSpecifierDict:specifier]; + + if ([[self type] isEqualToString:kIASKPSMultiValueSpecifier] || + [[self type] isEqualToString:kIASKPSTitleValueSpecifier]) { + [self _reinterpretValues:[self specifierDict]]; + } + } + return self; +} + +- (void)dealloc { + [_specifierDict release], _specifierDict = nil; + [_multipleValuesDict release], _multipleValuesDict = nil; + + _settingsReader = nil; + + [super dealloc]; +} + +- (void)_reinterpretValues:(NSDictionary*)specifierDict { + NSArray *values = [_specifierDict objectForKey:kIASKValues]; + NSArray *titles = [_specifierDict objectForKey:kIASKTitles]; + + NSMutableDictionary *multipleValuesDict = [[[NSMutableDictionary alloc] init] autorelease]; + + if (values) { + [multipleValuesDict setObject:values forKey:kIASKValues]; + } + + if (titles) { + [multipleValuesDict setObject:titles forKey:kIASKTitles]; + } + + [self setMultipleValuesDict:multipleValuesDict]; +} +- (NSString*)localizedObjectForKey:(NSString*)key { + return [self.settingsReader titleForStringId:[_specifierDict objectForKey:key]]; +} + +- (NSString*)title { + return [self localizedObjectForKey:kIASKTitle]; +} + +- (NSString*)footerText { + return [self localizedObjectForKey:kIASKFooterText]; +} + +-(Class) viewControllerClass { + return NSClassFromString([_specifierDict objectForKey:kIASKViewControllerClass]); +} + +-(SEL) viewControllerSelector { + return NSSelectorFromString([_specifierDict objectForKey:kIASKViewControllerSelector]); +} + +-(Class)buttonClass { + return NSClassFromString([_specifierDict objectForKey:kIASKButtonClass]); +} + +-(SEL)buttonAction { + return NSSelectorFromString([_specifierDict objectForKey:kIASKButtonAction]); +} + +- (NSString*)key { + return [_specifierDict objectForKey:kIASKKey]; +} + +- (NSString*)type { + return [_specifierDict objectForKey:kIASKType]; +} + +- (NSString*)titleForCurrentValue:(id)currentValue { + NSArray *values = [self multipleValues]; + NSArray *titles = [self multipleTitles]; + if (values.count != titles.count) { + return nil; + } + NSInteger keyIndex = [values indexOfObject:currentValue]; + if (keyIndex == NSNotFound) { + return nil; + } + @try { + return [self.settingsReader titleForStringId:[titles objectAtIndex:keyIndex]]; + } + @catch (NSException * e) {} + return nil; +} + +- (NSInteger)multipleValuesCount { + return [[_multipleValuesDict objectForKey:kIASKValues] count]; +} + +- (NSArray*)multipleValues { + return [_multipleValuesDict objectForKey:kIASKValues]; +} + +- (NSArray*)multipleTitles { + return [_multipleValuesDict objectForKey:kIASKTitles]; +} + +- (NSString*)file { + return [_specifierDict objectForKey:kIASKFile]; +} + +- (id)defaultValue { + return [_specifierDict objectForKey:kIASKDefaultValue]; +} + +- (id)defaultStringValue { + return [[_specifierDict objectForKey:kIASKDefaultValue] description]; +} + +- (BOOL)defaultBoolValue { + id defaultValue = [self defaultValue]; + if ([defaultValue isEqual:[self trueValue]]) { + return YES; + } + if ([defaultValue isEqual:[self falseValue]]) { + return NO; + } + return [defaultValue boolValue]; +} + +- (id)trueValue { + return [_specifierDict objectForKey:kIASKTrueValue]; +} + +- (id)falseValue { + return [_specifierDict objectForKey:kIASKFalseValue]; +} + +- (float)minimumValue { + return [[_specifierDict objectForKey:kIASKMinimumValue] floatValue]; +} + +- (float)maximumValue { + return [[_specifierDict objectForKey:kIASKMaximumValue] floatValue]; +} + +- (NSString*)minimumValueImage { + return [_specifierDict objectForKey:kIASKMinimumValueImage]; +} + +- (NSString*)maximumValueImage { + return [_specifierDict objectForKey:kIASKMaximumValueImage]; +} + +- (BOOL)isSecure { + return [[_specifierDict objectForKey:kIASKIsSecure] boolValue]; +} + +- (UIKeyboardType)keyboardType { + if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:kIASKKeyboardAlphabet]) { + return UIKeyboardTypeDefault; + } + else if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:kIASKKeyboardNumbersAndPunctuation]) { + return UIKeyboardTypeNumbersAndPunctuation; + } + else if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:kIASKKeyboardNumberPad]) { + return UIKeyboardTypeNumberPad; + } + else if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:kIASKKeyboardDecimalPad]) { + if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_4_1) { + return UIKeyboardTypeDecimalPad; + } + else { + return UIKeyboardTypeNumbersAndPunctuation; + } + } + else if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:KIASKKeyboardURL]) { + return UIKeyboardTypeURL; + } + else if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:kIASKKeyboardEmailAddress]) { + return UIKeyboardTypeEmailAddress; + } + return UIKeyboardTypeDefault; +} + +- (UITextAutocapitalizationType)autocapitalizationType { + if ([[_specifierDict objectForKey:kIASKAutocapitalizationType] isEqualToString:kIASKAutoCapNone]) { + return UITextAutocapitalizationTypeNone; + } + else if ([[_specifierDict objectForKey:kIASKAutocapitalizationType] isEqualToString:kIASKAutoCapSentences]) { + return UITextAutocapitalizationTypeSentences; + } + else if ([[_specifierDict objectForKey:kIASKAutocapitalizationType] isEqualToString:kIASKAutoCapWords]) { + return UITextAutocapitalizationTypeWords; + } + else if ([[_specifierDict objectForKey:kIASKAutocapitalizationType] isEqualToString:kIASKAutoCapAllCharacters]) { + return UITextAutocapitalizationTypeAllCharacters; + } + return UITextAutocapitalizationTypeNone; +} + +- (UITextAutocorrectionType)autoCorrectionType { + if ([[_specifierDict objectForKey:kIASKAutoCorrectionType] isEqualToString:kIASKAutoCorrDefault]) { + return UITextAutocorrectionTypeDefault; + } + else if ([[_specifierDict objectForKey:kIASKAutoCorrectionType] isEqualToString:kIASKAutoCorrNo]) { + return UITextAutocorrectionTypeNo; + } + else if ([[_specifierDict objectForKey:kIASKAutoCorrectionType] isEqualToString:kIASKAutoCorrYes]) { + return UITextAutocorrectionTypeYes; + } + return UITextAutocorrectionTypeDefault; +} + +@end diff --git a/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h b/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h new file mode 100644 index 000000000..7cc943b0a --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h @@ -0,0 +1,31 @@ +// +// IASKPSSliderSpecifierViewCell.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + +@class IASKSlider; + +@interface IASKPSSliderSpecifierViewCell : UITableViewCell { + IASKSlider *_slider; + UIImageView *_minImage; + UIImageView *_maxImage; +} + +@property (nonatomic, assign) IBOutlet IASKSlider *slider; +@property (nonatomic, assign) IBOutlet UIImageView *minImage; +@property (nonatomic, assign) IBOutlet UIImageView *maxImage; + +@end diff --git a/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m b/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m new file mode 100644 index 000000000..cbdca0279 --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m @@ -0,0 +1,72 @@ +// +// IASKPSSliderSpecifierViewCell.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009-2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKPSSliderSpecifierViewCell.h" +#import "IASKSlider.h" +#import "IASKSettingsReader.h" + +@implementation IASKPSSliderSpecifierViewCell + +@synthesize slider=_slider, + minImage=_minImage, + maxImage=_maxImage; + +- (void)layoutSubviews { + [super layoutSubviews]; + CGRect sliderBounds = _slider.bounds; + CGPoint sliderCenter = _slider.center; + const double superViewWidth = _slider.superview.frame.size.width; + + sliderCenter.x = superViewWidth / 2; + sliderBounds.size.width = superViewWidth - kIASKSliderNoImagesPadding * 2; + _minImage.hidden = YES; + _maxImage.hidden = YES; + + // Check if there are min and max images. If so, change the layout accordingly. + if (_minImage.image && _maxImage.image) { + // Both images + _minImage.hidden = NO; + _maxImage.hidden = NO; + sliderBounds.size.width = superViewWidth - kIASKSliderImagesPadding * 2; + } + else if (_minImage.image) { + // Min image + _minImage.hidden = NO; + sliderCenter.x += (kIASKSliderImagesPadding - kIASKSliderNoImagesPadding) / 2; + sliderBounds.size.width = superViewWidth - kIASKSliderNoImagesPadding - kIASKSliderImagesPadding; + } + else if (_maxImage.image) { + // Max image + _maxImage.hidden = NO; + sliderCenter.x -= (kIASKSliderImagesPadding - kIASKSliderNoImagesPadding) / 2; + sliderBounds.size.width = superViewWidth - kIASKSliderNoImagesPadding - kIASKSliderImagesPadding; + } + + _slider.bounds = sliderBounds; + _slider.center = sliderCenter; +} + +- (void)dealloc { + _minImage.image = nil; + _maxImage.image = nil; + [super dealloc]; +} + +- (void)prepareForReuse { + _minImage.image = nil; + _maxImage.image = nil; +} +@end diff --git a/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h b/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h new file mode 100644 index 000000000..b4d70c8ad --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h @@ -0,0 +1,29 @@ +// +// IASKPSTextFieldSpecifierViewCell.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + +@class IASKTextField; + +@interface IASKPSTextFieldSpecifierViewCell : UITableViewCell { + UILabel *_label; + IASKTextField *_textField; +} + +@property (nonatomic, assign) IBOutlet UILabel *label; +@property (nonatomic, assign) IBOutlet IASKTextField *textField; + +@end diff --git a/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m b/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m new file mode 100644 index 000000000..cf7486eea --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m @@ -0,0 +1,52 @@ +// +// IASKPSTextFieldSpecifierViewCell.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009-2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKPSTextFieldSpecifierViewCell.h" +#import "IASKTextField.h" +#import "IASKSettingsReader.h" + +@implementation IASKPSTextFieldSpecifierViewCell + +@synthesize label=_label, + textField=_textField; + +- (void)layoutSubviews { + [super layoutSubviews]; + CGSize labelSize = [_label sizeThatFits:CGSizeZero]; + labelSize.width = MIN(labelSize.width, _label.bounds.size.width); + + CGRect textFieldFrame = _textField.frame; + textFieldFrame.origin.x = _label.frame.origin.x + MAX(kIASKMinLabelWidth, labelSize.width) + kIASKSpacing; + if (!_label.text.length) + textFieldFrame.origin.x = _label.frame.origin.x; + textFieldFrame.size.width = _textField.superview.frame.size.width - textFieldFrame.origin.x - _label.frame.origin.x; + _textField.frame = textFieldFrame; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + + +- (void)dealloc { + [super dealloc]; +} + + +@end diff --git a/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.h b/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.h new file mode 100644 index 000000000..b3185b410 --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.h @@ -0,0 +1,22 @@ +// +// IASKPSTitleValueSpecifierViewCell.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + + +@interface IASKPSTitleValueSpecifierViewCell : UITableViewCell + +@end diff --git a/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.m b/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.m new file mode 100644 index 000000000..c1d5aaa55 --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.m @@ -0,0 +1,57 @@ +// +// IASKPSTitleValueSpecifierViewCell.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKPSTitleValueSpecifierViewCell.h" +#import "IASKSettingsReader.h" + + +@implementation IASKPSTitleValueSpecifierViewCell + +- (void)layoutSubviews { + // left align the value if the title is empty + if (!self.textLabel.text.length) { + self.textLabel.text = self.detailTextLabel.text; + self.detailTextLabel.text = nil; + if ([self.reuseIdentifier isEqualToString:kIASKPSMultiValueSpecifier]) { + self.textLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]]; + self.textLabel.textColor = self.detailTextLabel.textColor; + } + } + [super layoutSubviews]; + + CGSize viewSize = [self.textLabel superview].frame.size; + + //if there's an image, make room for it + CGFloat imageOffset = self.imageView.image ? self.imageView.bounds.size.width + self.imageView.frame.origin.x : 0; + + // set the left title label frame + CGFloat labelWidth = [self.textLabel sizeThatFits:CGSizeZero].width; + CGFloat minValueWidth = (self.detailTextLabel.text.length) ? kIASKMinValueWidth + kIASKSpacing : 0; + labelWidth = MIN(labelWidth, viewSize.width - minValueWidth - kIASKPaddingLeft -kIASKPaddingRight - imageOffset); + CGRect labelFrame = CGRectMake(kIASKPaddingLeft + imageOffset, 0, labelWidth, viewSize.height -2); + self.textLabel.frame = labelFrame; + + // set the right value label frame + if (self.detailTextLabel.text.length) { + CGRect valueFrame = CGRectMake(kIASKPaddingLeft + labelWidth + kIASKSpacing + imageOffset, + 0, + viewSize.width - (kIASKPaddingLeft + labelWidth + kIASKSpacing + imageOffset) - kIASKPaddingRight, + viewSize.height -2); + self.detailTextLabel.frame = valueFrame; + } +} + +@end diff --git a/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.h b/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.h new file mode 100644 index 000000000..a6d2864bc --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.h @@ -0,0 +1,29 @@ +// +// IASKPSToggleSwitchSpecifierViewCell.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + +@class IASKSwitch; + +@interface IASKPSToggleSwitchSpecifierViewCell : UITableViewCell { + UILabel *_label; + IASKSwitch *_toggle; +} + +@property (nonatomic, assign) IBOutlet UILabel *label; +@property (nonatomic, assign) IBOutlet IASKSwitch *toggle; + +@end diff --git a/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.m b/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.m new file mode 100644 index 000000000..13c66e285 --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.m @@ -0,0 +1,62 @@ +// +// IASKPSToggleSwitchSpecifierViewCell.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKPSToggleSwitchSpecifierViewCell.h" +#import "IASKSwitch.h" +#import "IASKSettingsReader.h" + +@implementation IASKPSToggleSwitchSpecifierViewCell + +@synthesize label=_label, + toggle=_toggle; + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { + // Initialization code + } + return self; +} + + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + + +- (void)dealloc { + [super dealloc]; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + if(self.imageView.image) { + //resize the label to make room for the image + self.label.frame = CGRectMake(CGRectGetWidth(self.imageView.bounds) + self.imageView.frame.origin.x + kIASKSpacing, + self.label.frame.origin.y, + self.toggle.frame.origin.x - CGRectGetWidth(self.imageView.bounds) - 2.f * kIASKSpacing, + self.label.frame.size.height); + } else { + self.label.frame = CGRectMake(kIASKPaddingLeft, + self.label.frame.origin.y, + self.toggle.frame.origin.x - kIASKSpacing - kIASKPaddingLeft, + self.label.frame.size.height); + } +} + +@end diff --git a/InAppSettingsKit/Views/IASKSlider.h b/InAppSettingsKit/Views/IASKSlider.h new file mode 100644 index 000000000..34c5ecbbe --- /dev/null +++ b/InAppSettingsKit/Views/IASKSlider.h @@ -0,0 +1,26 @@ +// +// IASKSlider.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + + +@interface IASKSlider : UISlider { + NSString *_key; +} + +@property (nonatomic, retain) NSString *key; + +@end diff --git a/InAppSettingsKit/Views/IASKSlider.m b/InAppSettingsKit/Views/IASKSlider.m new file mode 100644 index 000000000..d591ff298 --- /dev/null +++ b/InAppSettingsKit/Views/IASKSlider.m @@ -0,0 +1,30 @@ +// +// IASKSlider.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSlider.h" + + +@implementation IASKSlider + +@synthesize key=_key; + +- (void)dealloc { + [_key release], _key = nil; + + [super dealloc]; +} + +@end diff --git a/InAppSettingsKit/Views/IASKSwitch.h b/InAppSettingsKit/Views/IASKSwitch.h new file mode 100644 index 000000000..b1439bd1c --- /dev/null +++ b/InAppSettingsKit/Views/IASKSwitch.h @@ -0,0 +1,26 @@ +// +// IASKSwitch.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + + +@interface IASKSwitch : UISwitch { + NSString *_key; +} + +@property (nonatomic, retain) NSString *key; + +@end diff --git a/InAppSettingsKit/Views/IASKSwitch.m b/InAppSettingsKit/Views/IASKSwitch.m new file mode 100644 index 000000000..f32aba4d3 --- /dev/null +++ b/InAppSettingsKit/Views/IASKSwitch.m @@ -0,0 +1,31 @@ +// +// IASKSwitch.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSwitch.h" + + +@implementation IASKSwitch + +@synthesize key=_key; + +- (void)dealloc { + [_key release], _key = nil; + + [super dealloc]; +} + + +@end diff --git a/InAppSettingsKit/Views/IASKTextField.h b/InAppSettingsKit/Views/IASKTextField.h new file mode 100644 index 000000000..47c9be375 --- /dev/null +++ b/InAppSettingsKit/Views/IASKTextField.h @@ -0,0 +1,26 @@ +// +// IASKTextField.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + + +@interface IASKTextField : UITextField { + NSString *_key; +} + +@property (nonatomic, retain) NSString *key; + +@end diff --git a/InAppSettingsKit/Views/IASKTextField.m b/InAppSettingsKit/Views/IASKTextField.m new file mode 100644 index 000000000..9056896f4 --- /dev/null +++ b/InAppSettingsKit/Views/IASKTextField.m @@ -0,0 +1,30 @@ +// +// IASKTextField.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKTextField.h" + + +@implementation IASKTextField + +@synthesize key=_key; + +- (void)dealloc { + [_key release], _key = nil; + + [super dealloc]; +} + +@end diff --git a/InAppSettingsKit/Xibs/IASKAppSettingsView.xib b/InAppSettingsKit/Xibs/IASKAppSettingsView.xib new file mode 100644 index 000000000..74720fae3 --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKAppSettingsView.xib @@ -0,0 +1,222 @@ + + + + 1280 + 11B26 + 1934 + 1138 + 566.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 931 + + + YES + IBProxyObject + IBUITableView + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + {320, 460} + + + + 10 + + 549453824 + {512, 1} + + YES + + YES + + + + TU0AKgAACAjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/wANAQAAAwAAAAECAAAAAQEAAwAAAAEAAQAAAQIAAwAAAAQAAAiqAQMAAwAA +AAEAAQAAAQYAAwAAAAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAA +AAEAAQAAARcABAAAAAEAAAgAARwAAwAAAAEAAQAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAAAiyAAAAAAAI +AAgACAAIAAEAAQABAAE + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + NO + YES + NO + IBCocoaTouchFramework + NO + 1 + 1 + 0 + YES + 44 + 10 + 10 + + + + + YES + + + view + + + + 10 + + + + dataSource + + + + 6 + + + + delegate + + + + 7 + + + + + YES + + 0 + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + YES + + YES + -1.CustomClassName + -1.IBPluginDependency + -2.CustomClassName + -2.IBPluginDependency + 4.IBPluginDependency + + + YES + IASKAppSettingsViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + + + + YES + + + + + 10 + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + 3 + 931 + + diff --git a/InAppSettingsKit/Xibs/IASKAppSettingsWebView.xib b/InAppSettingsKit/Xibs/IASKAppSettingsWebView.xib new file mode 100644 index 000000000..b814f05fc --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKAppSettingsWebView.xib @@ -0,0 +1,378 @@ + + + + 1024 + 10F569 + 804 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 123 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + + YES + + + 274 + {320, 460} + + + 3 + MQA + + IBCocoaTouchFramework + + + {320, 460} + + + + IBCocoaTouchFramework + + + + + YES + + + view + + + + 3 + + + + webView + + + + 5 + + + + delegate + + + + 6 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 4.IBPluginDependency + + + YES + IASKAppSettingsWebViewController + UIResponder + {{354, 412}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 6 + + + + YES + + IASKAppSettingsWebViewController + UIViewController + + webView + UIWebView + + + webView + + webView + UIWebView + + + + IBProjectSource + ../InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWebView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWebView.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../InAppSettingsKitSampleApp.xcodeproj + 3 + 123 + + diff --git a/InAppSettingsKit/Xibs/IASKPSSliderSpecifierViewCell.xib b/InAppSettingsKit/Xibs/IASKPSSliderSpecifierViewCell.xib new file mode 100644 index 000000000..67750384e --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKPSSliderSpecifierViewCell.xib @@ -0,0 +1,251 @@ + + + + 1296 + 11D50 + 2182 + 1138.32 + 568.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1179 + + + YES + IBUISlider + IBUITableViewCell + IBUIImageView + IBProxyObject + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 290 + + YES + + + 256 + + YES + + + 290 + {{52, 12}, {216, 23}} + + + NO + YES + YES + IBCocoaTouchFramework + 0 + 0 + 0.5 + NO + + + + 289 + {{289, 13}, {21, 21}} + + + NO + NO + 8 + NO + IBCocoaTouchFramework + + + + 292 + {{10, 13}, {21, 21}} + + + NO + NO + 7 + NO + IBCocoaTouchFramework + + + {320, 43} + + + + 3 + MCAwAA + + NO + YES + 4 + YES + IBCocoaTouchFramework + + + {320, 44} + + + + 1 + MC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEAA + + YES + NO + IBCocoaTouchFramework + 0 + + PSSliderSpecifier + + + + + YES + + + slider + + + + 12 + + + + maxImage + + + + 13 + + + + minImage + + + + 14 + + + + + YES + + 0 + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + + + + 3 + + + + + 6 + + + + + 9 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.CustomClassName + -2.IBPluginDependency + 2.CustomClassName + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 6.IBPluginDependency + 9.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKPSSliderSpecifierViewCell + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKSlider + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + + + + YES + + + + + 14 + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + 3 + 1179 + + diff --git a/InAppSettingsKit/Xibs/IASKPSTextFieldSpecifierViewCell.xib b/InAppSettingsKit/Xibs/IASKPSTextFieldSpecifierViewCell.xib new file mode 100644 index 000000000..43a553b9c --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKPSTextFieldSpecifierViewCell.xib @@ -0,0 +1,254 @@ + + + + 1296 + 11D50 + 2182 + 1138.32 + 568.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1179 + + + YES + IBUITableViewCell + IBUILabel + IBUITextField + IBProxyObject + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 290 + + YES + + + 256 + + YES + + + 294 + {{9, 11}, {240, 21}} + + NO + YES + NO + IBCocoaTouchFramework + Label + + 1 + MCAwIDAAA + + + 1 + 10 + + Helvetica-Bold + Helvetica + 2 + 17 + + + Helvetica-Bold + 17 + 16 + + + + + 291 + {{100, 11}, {201, 21}} + + NO + NO + IBCocoaTouchFramework + hello + + 1 + MC4yNzQ1MDk4MiAwLjM3NjQ3MDYgMC41MjE1Njg2NgA + + YES + 10 + + 9 + IBCocoaTouchFramework + + + Helvetica + Helvetica + 0 + 17 + + + Helvetica + 17 + 16 + + + + {320, 43} + + + 3 + MCAwAA + + NO + YES + 4 + YES + IBCocoaTouchFramework + + + {320, 44} + + + 1 + MC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEAA + + YES + NO + IBCocoaTouchFramework + 0 + + PSTextFieldSpecifier + + + + + YES + + + label + + + + 8 + + + + textField + + + + 9 + + + + + YES + + 0 + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + + + 3 + + + + + 4 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.CustomClassName + -2.IBPluginDependency + 2.CustomClassName + 2.IBPluginDependency + 3.IBPluginDependency + 4.CustomClassName + 4.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKPSTextFieldSpecifierViewCell + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKTextField + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + + + + YES + + + + + 9 + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + 3 + 1179 + + diff --git a/InAppSettingsKit/Xibs/IASKPSToggleSwitchSpecifierViewCell.xib b/InAppSettingsKit/Xibs/IASKPSToggleSwitchSpecifierViewCell.xib new file mode 100644 index 000000000..2e5803f2e --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKPSToggleSwitchSpecifierViewCell.xib @@ -0,0 +1,237 @@ + + + + 1296 + 11D50 + 2182 + 1138.32 + 568.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1179 + + + YES + IBUITableViewCell + IBUISwitch + IBUILabel + IBProxyObject + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 290 + + YES + + + 256 + + YES + + + 294 + {{9, 10}, {200, 21}} + + NO + YES + NO + IBCocoaTouchFramework + Label + + 1 + MCAwIDAAA + + + 1 + 10 + + Helvetica-Bold + Helvetica + 2 + 17 + + + Helvetica-Bold + 17 + 16 + + + + + 289 + {{218, 8}, {94, 27}} + + NO + YES + YES + IBCocoaTouchFramework + 0 + 0 + YES + + + {320, 43} + + + 3 + MCAwAA + + NO + YES + 4 + YES + IBCocoaTouchFramework + + + {320, 44} + + + 1 + MC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEAA + + YES + NO + IBCocoaTouchFramework + 0 + + PSToggleSwitchSpecifier + + + + + YES + + + toggle + + + + 8 + + + + label + + + + 9 + + + + + YES + + 0 + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + Toggle Switch Specifier View Cell - PSToggleSwitchSpecifier + + + 3 + + + + + 4 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.CustomClassName + -2.IBPluginDependency + 2.CustomClassName + 2.IBPluginDependency + 3.IBPluginDependency + 4.CustomClassName + 4.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKPSToggleSwitchSpecifierViewCell + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKSwitch + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + + + + YES + + + + + 9 + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + 3 + 1179 + + diff --git a/InAppSettingsKit/Xibs/IASKSpecifierValuesView.xib b/InAppSettingsKit/Xibs/IASKSpecifierValuesView.xib new file mode 100644 index 000000000..9c7ff86e6 --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKSpecifierValuesView.xib @@ -0,0 +1,255 @@ + + + + 768 + 10J567 + 1294 + 1038.35 + 462.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 294 + + + YES + IBProxyObject + IBUIView + IBUITableView + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 292 + + YES + + + 274 + {320, 460} + + + + + 10 + + 549453824 + {84, 1} + + YES + + YES + + + + TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADQEAAAMAAAABAFQAAAEB +AAMAAAABAAEAAAECAAMAAAAEAAAB+gEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAAEAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS +AAMAAAABAAEAAAFTAAMAAAAEAAACAgAAAAAACAAIAAgACAABAAEAAQABA + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + NO + YES + NO + IBCocoaTouchFramework + NO + 1 + 1 + 0 + YES + 44 + 10 + 10 + + + {320, 460} + + + + + 3 + MQA + + 2 + + + IBCocoaTouchFramework + + + + + YES + + + view + + + + 3 + + + + dataSource + + + + 5 + + + + delegate + + + + 6 + + + + _tableView + + + + 7 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 4.IBPluginDependency + + + YES + IASKSpecifierValuesViewController + UIResponder + {{556, 432}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + + + + YES + + + + + 7 + + + + YES + + IASKSpecifierValuesViewController + UIViewController + + _tableView + UITableView + + + _tableView + + _tableView + UITableView + + + + IBProjectSource + ./Classes/IASKSpecifierValuesViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + 3 + 294 + + diff --git a/PhoneMainView.xib b/PhoneMainView.xib index 8cc1896dd..0052d5e1c 100644 --- a/PhoneMainView.xib +++ b/PhoneMainView.xib @@ -2,13 +2,13 @@ 784 - 11D50b - 2182 - 1138.32 - 568.00 + 11C74 + 1938 + 1138.23 + 567.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1181 + 933 YES @@ -19,6 +19,9 @@ IBUITabBarController IBUIWindow IBUITabBar + IBUINavigationController + IBUINavigationBar + IBUINavigationItem YES @@ -42,11 +45,10 @@ IBCocoaTouchFramework - + 1316 {320, 480} - 1 MSAxIDEAA @@ -65,15 +67,10 @@ IBCocoaTouchFramework NO - - History - - History - - NSImage - history-orange.png - + + IBCocoaTouchFramework + 0 @@ -81,12 +78,87 @@ 1 1 + YES IBCocoaTouchFramework NO + + + 256 + {0, 0} + _NS:451 + NO + YES + YES + IBCocoaTouchFramework + + + YES + + Informations + + Information + IBCocoaTouchFramework + + + MoreViewController + + 1 + 1 + + IBCocoaTouchFramework + NO + + YES - + + Call logs + + History + + NSImage + history-orange.png + + IBCocoaTouchFramework + + + + + 1 + 1 + + YES + IBCocoaTouchFramework + NO + + + 256 + {0, 0} + _NS:451 + NO + YES + YES + IBCocoaTouchFramework + + + YES + + Call logs + + Call logs + IBCocoaTouchFramework + + + + 1 + 1 + + IBCocoaTouchFramework + NO + + + Dialer @@ -106,26 +178,12 @@ IBCocoaTouchFramework NO - - + + IBCocoaTouchFramework 5 - - 1 - 1 - - IBCocoaTouchFramework - NO - - - - - IBCocoaTouchFramework - 0 - - 1 @@ -134,12 +192,59 @@ IBCocoaTouchFramework NO + + + Settings + + NSImage + 20-gear2.png + + IBCocoaTouchFramework + + + + + 1 + 1 + + YES + IBCocoaTouchFramework + NO + + + 256 + {0, 0} + _NS:451 + NO + YES + YES + IBCocoaTouchFramework + + + YES + + + Root View Controller + IBCocoaTouchFramework + + + + 1 + 1 + + IBCocoaTouchFramework + NO + + + + 266 {{0, 431}, {320, 49}} + 3 MCAwAA @@ -176,6 +281,38 @@ 14 + + + myPhoneViewController + + + + 51 + + + + moreNavigationController + + + + 58 + + + + settingsController + + + + 74 + + + + myTabBarController + + + + 59 + @@ -216,10 +353,11 @@ YES - - - + + + + @@ -228,21 +366,6 @@ - - 11 - - - YES - - - - Contacts - - - 12 - - - 38 @@ -259,34 +382,124 @@ - 41 - + 53 + YES - + + + - history - 42 - - + 54 + + - 43 - + 55 + YES - + - - more + - 44 - - + 56 + + + + + 57 + + + + + 66 + + + YES + + + + dummy-contact-replaced-in-code + + + 67 + + + + + 69 + + + YES + + + + + + + + 70 + + + + + 71 + + + YES + + + + + + 72 + + + + + 73 + + + + + 75 + + + YES + + + + + + + + 76 + + + + + 77 + + + YES + + + + + + 78 + + + + + 79 + + @@ -298,8 +511,6 @@ -1.IBPluginDependency -2.CustomClassName -2.IBPluginDependency - 11.IBPluginDependency - 12.IBPluginDependency 2.IBAttributePlaceholdersKey 2.IBPluginDependency 38.CustomClassName @@ -307,23 +518,35 @@ 39.IBPluginDependency 4.CustomClassName 4.IBPluginDependency - 41.CustomClassName - 41.IBPluginDependency - 42.IBPluginDependency - 43.CustomClassName - 43.IBPluginDependency - 44.IBPluginDependency + 53.IBPluginDependency + 54.IBPluginDependency + 55.CustomClassName + 55.IBPluginDependency + 56.IBPluginDependency + 57.IBPluginDependency + 66.IBPluginDependency + 67.IBPluginDependency + 69.IBPluginDependency + 70.IBPluginDependency + 71.CustomClassName + 71.IBPluginDependency + 72.IBPluginDependency + 73.IBPluginDependency + 75.IBPluginDependency + 76.IBPluginDependency + 77.CustomClassName + 77.IBPluginDependency + 78.IBPluginDependency + 79.IBPluginDependency 8.IBPluginDependency 9.IBPluginDependency - + YES UIApplication com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin YES @@ -335,7 +558,6 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin linphoneAppDelegate com.apple.InterfaceBuilder.IBCocoaTouchPlugin - CallHistoryTableViewController com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin MoreViewController @@ -343,6 +565,21 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKAppSettingsViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + CallHistoryTableViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -357,7 +594,7 @@ - 48 + 79 0 @@ -366,10 +603,6 @@ com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 @@ -380,15 +613,17 @@ YES YES + 20-gear2.png dialer-orange.png history-orange.png - + YES + {26, 28} {25, 24} {25, 23} - 1181 + 933 diff --git a/Settings.bundle/Root.plist b/Settings.bundle/Root.plist index 4b6332f8e..bd5c9216c 100644 --- a/Settings.bundle/Root.plist +++ b/Settings.bundle/Root.plist @@ -94,6 +94,16 @@ Type PSToggleSwitchSpecifier + + Type + PSToggleSwitchSpecifier + Title + Enable video + Key + enable_video_preference + DefaultValue + + Title diff --git a/Settings.bundle/video.plist b/Settings.bundle/video.plist index 440f5ad90..56af43866 100644 --- a/Settings.bundle/video.plist +++ b/Settings.bundle/video.plist @@ -4,16 +4,6 @@ PreferenceSpecifiers - - Type - PSToggleSwitchSpecifier - Title - Enable video - Key - enable_video_preference - DefaultValue - - Type PSToggleSwitchSpecifier diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index b59ceb3c1..806364d34 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -220,6 +220,52 @@ 340751E8150F38FD00B89C47 /* UIToggleVideoButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 340751E6150F38FD00B89C47 /* UIToggleVideoButton.m */; }; 340A75B014C0670B006AA708 /* ConferenceCallDetailView-ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 340A75AF14C0670A006AA708 /* ConferenceCallDetailView-ipad.xib */; }; 340A75B114C0670B006AA708 /* ConferenceCallDetailView-ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 340A75AF14C0670A006AA708 /* ConferenceCallDetailView-ipad.xib */; }; + 34151FE01563A8D800205A0E /* IASKAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FB91563A8D800205A0E /* IASKAppSettingsViewController.m */; }; + 34151FE11563A8D800205A0E /* IASKAppSettingsWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FBB1563A8D800205A0E /* IASKAppSettingsWebViewController.m */; }; + 34151FE21563A8D800205A0E /* IASKSpecifierValuesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FBD1563A8D800205A0E /* IASKSpecifierValuesViewController.m */; }; + 34151FE31563A8D800205A0E /* IASKSettingsReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FC11563A8D800205A0E /* IASKSettingsReader.m */; }; + 34151FE41563A8D800205A0E /* IASKSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FC31563A8D800205A0E /* IASKSettingsStore.m */; }; + 34151FE51563A8D800205A0E /* IASKSettingsStoreFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FC51563A8D800205A0E /* IASKSettingsStoreFile.m */; }; + 34151FE61563A8D800205A0E /* IASKSettingsStoreUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FC71563A8D800205A0E /* IASKSettingsStoreUserDefaults.m */; }; + 34151FE71563A8D800205A0E /* IASKSpecifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FC91563A8D800205A0E /* IASKSpecifier.m */; }; + 34151FE81563A8D800205A0E /* IASKPSSliderSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FCC1563A8D800205A0E /* IASKPSSliderSpecifierViewCell.m */; }; + 34151FE91563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FCE1563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.m */; }; + 34151FEA1563A8D800205A0E /* IASKPSTitleValueSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FD01563A8D800205A0E /* IASKPSTitleValueSpecifierViewCell.m */; }; + 34151FEB1563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FD21563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.m */; }; + 34151FEC1563A8D800205A0E /* IASKSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FD41563A8D800205A0E /* IASKSlider.m */; }; + 34151FED1563A8D800205A0E /* IASKSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FD61563A8D800205A0E /* IASKSwitch.m */; }; + 34151FEE1563A8D800205A0E /* IASKTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FD81563A8D800205A0E /* IASKTextField.m */; }; + 34151FEF1563A8D800205A0E /* IASKAppSettingsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDA1563A8D800205A0E /* IASKAppSettingsView.xib */; }; + 34151FF01563A8D800205A0E /* IASKAppSettingsWebView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDB1563A8D800205A0E /* IASKAppSettingsWebView.xib */; }; + 34151FF11563A8D800205A0E /* IASKPSSliderSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDC1563A8D800205A0E /* IASKPSSliderSpecifierViewCell.xib */; }; + 34151FF21563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDD1563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.xib */; }; + 34151FF31563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDE1563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.xib */; }; + 34151FF41563A8D800205A0E /* IASKSpecifierValuesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDF1563A8D800205A0E /* IASKSpecifierValuesView.xib */; }; + 34151FF61563A92100205A0E /* IASKAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FB91563A8D800205A0E /* IASKAppSettingsViewController.m */; }; + 34151FF71563A92100205A0E /* IASKAppSettingsWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FBB1563A8D800205A0E /* IASKAppSettingsWebViewController.m */; }; + 34151FF81563A92100205A0E /* IASKSpecifierValuesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FBD1563A8D800205A0E /* IASKSpecifierValuesViewController.m */; }; + 34151FF91563A92900205A0E /* IASKSettingsReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FC11563A8D800205A0E /* IASKSettingsReader.m */; }; + 34151FFA1563A92900205A0E /* IASKSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FC31563A8D800205A0E /* IASKSettingsStore.m */; }; + 34151FFB1563A92900205A0E /* IASKSettingsStoreFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FC51563A8D800205A0E /* IASKSettingsStoreFile.m */; }; + 34151FFC1563A92900205A0E /* IASKSettingsStoreUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FC71563A8D800205A0E /* IASKSettingsStoreUserDefaults.m */; }; + 34151FFD1563A92900205A0E /* IASKSpecifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FC91563A8D800205A0E /* IASKSpecifier.m */; }; + 34151FFE1563A93400205A0E /* IASKPSSliderSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FCC1563A8D800205A0E /* IASKPSSliderSpecifierViewCell.m */; }; + 34151FFF1563A93400205A0E /* IASKPSTextFieldSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FCE1563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.m */; }; + 341520001563A93400205A0E /* IASKPSTitleValueSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FD01563A8D800205A0E /* IASKPSTitleValueSpecifierViewCell.m */; }; + 341520011563A93400205A0E /* IASKPSToggleSwitchSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FD21563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.m */; }; + 341520021563A93400205A0E /* IASKSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FD41563A8D800205A0E /* IASKSlider.m */; }; + 341520031563A93400205A0E /* IASKSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FD61563A8D800205A0E /* IASKSwitch.m */; }; + 341520041563A93400205A0E /* IASKTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 34151FD81563A8D800205A0E /* IASKTextField.m */; }; + 341520051563A93B00205A0E /* IASKAppSettingsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDA1563A8D800205A0E /* IASKAppSettingsView.xib */; }; + 341520061563A93B00205A0E /* IASKAppSettingsWebView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDB1563A8D800205A0E /* IASKAppSettingsWebView.xib */; }; + 341520071563A93B00205A0E /* IASKPSSliderSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDC1563A8D800205A0E /* IASKPSSliderSpecifierViewCell.xib */; }; + 341520081563A93B00205A0E /* IASKPSTextFieldSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDD1563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.xib */; }; + 341520091563A93B00205A0E /* IASKPSToggleSwitchSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDE1563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.xib */; }; + 3415200A1563A93B00205A0E /* IASKSpecifierValuesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34151FDF1563A8D800205A0E /* IASKSpecifierValuesView.xib */; }; + 3415205A1563AA8F00205A0E /* 20-gear2.png in Resources */ = {isa = PBXBuildFile; fileRef = 341520591563AA8F00205A0E /* 20-gear2.png */; }; + 3415205C1563ABEB00205A0E /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3415205B1563ABEB00205A0E /* MessageUI.framework */; }; + 3415207B156BBEC000205A0E /* LinphoneCoreSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 3415207A156BBEC000205A0E /* LinphoneCoreSettingsStore.m */; }; + 3415207C156BBEC000205A0E /* LinphoneCoreSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 3415207A156BBEC000205A0E /* LinphoneCoreSettingsStore.m */; }; 3418843714C58BB100EA48C7 /* nowebcamCIF.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 3418843614C58BB100EA48C7 /* nowebcamCIF.jpg */; }; 3418843814C58BB100EA48C7 /* nowebcamCIF.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 3418843614C58BB100EA48C7 /* nowebcamCIF.jpg */; }; 3418844814C6CAD300EA48C7 /* StatusSubViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3418844614C6CAD300EA48C7 /* StatusSubViewController.m */; }; @@ -622,6 +668,47 @@ 340751E5150F38FC00B89C47 /* UIToggleVideoButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIToggleVideoButton.h; sourceTree = ""; }; 340751E6150F38FD00B89C47 /* UIToggleVideoButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIToggleVideoButton.m; sourceTree = ""; }; 340A75AF14C0670A006AA708 /* ConferenceCallDetailView-ipad.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "ConferenceCallDetailView-ipad.xib"; sourceTree = ""; }; + 34151FB81563A8D800205A0E /* IASKAppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKAppSettingsViewController.h; sourceTree = ""; }; + 34151FB91563A8D800205A0E /* IASKAppSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKAppSettingsViewController.m; sourceTree = ""; }; + 34151FBA1563A8D800205A0E /* IASKAppSettingsWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKAppSettingsWebViewController.h; sourceTree = ""; }; + 34151FBB1563A8D800205A0E /* IASKAppSettingsWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKAppSettingsWebViewController.m; sourceTree = ""; }; + 34151FBC1563A8D800205A0E /* IASKSpecifierValuesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSpecifierValuesViewController.h; sourceTree = ""; }; + 34151FBD1563A8D800205A0E /* IASKSpecifierValuesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSpecifierValuesViewController.m; sourceTree = ""; }; + 34151FBE1563A8D800205A0E /* IASKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKViewController.h; sourceTree = ""; }; + 34151FC01563A8D800205A0E /* IASKSettingsReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSettingsReader.h; sourceTree = ""; }; + 34151FC11563A8D800205A0E /* IASKSettingsReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSettingsReader.m; sourceTree = ""; }; + 34151FC21563A8D800205A0E /* IASKSettingsStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSettingsStore.h; sourceTree = ""; }; + 34151FC31563A8D800205A0E /* IASKSettingsStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSettingsStore.m; sourceTree = ""; }; + 34151FC41563A8D800205A0E /* IASKSettingsStoreFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSettingsStoreFile.h; sourceTree = ""; }; + 34151FC51563A8D800205A0E /* IASKSettingsStoreFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSettingsStoreFile.m; sourceTree = ""; }; + 34151FC61563A8D800205A0E /* IASKSettingsStoreUserDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSettingsStoreUserDefaults.h; sourceTree = ""; }; + 34151FC71563A8D800205A0E /* IASKSettingsStoreUserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSettingsStoreUserDefaults.m; sourceTree = ""; }; + 34151FC81563A8D800205A0E /* IASKSpecifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSpecifier.h; sourceTree = ""; }; + 34151FC91563A8D800205A0E /* IASKSpecifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSpecifier.m; sourceTree = ""; }; + 34151FCB1563A8D800205A0E /* IASKPSSliderSpecifierViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKPSSliderSpecifierViewCell.h; sourceTree = ""; }; + 34151FCC1563A8D800205A0E /* IASKPSSliderSpecifierViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKPSSliderSpecifierViewCell.m; sourceTree = ""; }; + 34151FCD1563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKPSTextFieldSpecifierViewCell.h; sourceTree = ""; }; + 34151FCE1563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKPSTextFieldSpecifierViewCell.m; sourceTree = ""; }; + 34151FCF1563A8D800205A0E /* IASKPSTitleValueSpecifierViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKPSTitleValueSpecifierViewCell.h; sourceTree = ""; }; + 34151FD01563A8D800205A0E /* IASKPSTitleValueSpecifierViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKPSTitleValueSpecifierViewCell.m; sourceTree = ""; }; + 34151FD11563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKPSToggleSwitchSpecifierViewCell.h; sourceTree = ""; }; + 34151FD21563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKPSToggleSwitchSpecifierViewCell.m; sourceTree = ""; }; + 34151FD31563A8D800205A0E /* IASKSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSlider.h; sourceTree = ""; }; + 34151FD41563A8D800205A0E /* IASKSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSlider.m; sourceTree = ""; }; + 34151FD51563A8D800205A0E /* IASKSwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSwitch.h; sourceTree = ""; }; + 34151FD61563A8D800205A0E /* IASKSwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSwitch.m; sourceTree = ""; }; + 34151FD71563A8D800205A0E /* IASKTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKTextField.h; sourceTree = ""; }; + 34151FD81563A8D800205A0E /* IASKTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKTextField.m; sourceTree = ""; }; + 34151FDA1563A8D800205A0E /* IASKAppSettingsView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKAppSettingsView.xib; sourceTree = ""; }; + 34151FDB1563A8D800205A0E /* IASKAppSettingsWebView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKAppSettingsWebView.xib; sourceTree = ""; }; + 34151FDC1563A8D800205A0E /* IASKPSSliderSpecifierViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKPSSliderSpecifierViewCell.xib; sourceTree = ""; }; + 34151FDD1563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKPSTextFieldSpecifierViewCell.xib; sourceTree = ""; }; + 34151FDE1563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKPSToggleSwitchSpecifierViewCell.xib; sourceTree = ""; }; + 34151FDF1563A8D800205A0E /* IASKSpecifierValuesView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKSpecifierValuesView.xib; sourceTree = ""; }; + 341520591563AA8F00205A0E /* 20-gear2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "20-gear2.png"; path = "Resources/20-gear2.png"; sourceTree = ""; }; + 3415205B1563ABEB00205A0E /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; + 34152079156BBEC000205A0E /* LinphoneCoreSettingsStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinphoneCoreSettingsStore.h; sourceTree = ""; }; + 3415207A156BBEC000205A0E /* LinphoneCoreSettingsStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneCoreSettingsStore.m; sourceTree = ""; }; 3418843614C58BB100EA48C7 /* nowebcamCIF.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = nowebcamCIF.jpg; path = submodules/linphone/mediastreamer2/src/nowebcamCIF.jpg; sourceTree = ""; }; 3418844514C6CAD300EA48C7 /* StatusSubViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StatusSubViewController.h; sourceTree = ""; }; 3418844614C6CAD300EA48C7 /* StatusSubViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StatusSubViewController.m; sourceTree = ""; }; @@ -667,6 +754,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 3415205C1563ABEB00205A0E /* MessageUI.framework in Frameworks */, 340751971506459A00B89C47 /* CoreTelephony.framework in Frameworks */, 226CDADF14E2D0B800513B67 /* libbcg729.a in Frameworks */, 226CDAE014E2D0B800513B67 /* libmsbcg729.a in Frameworks */, @@ -809,6 +897,8 @@ 3418844714C6CAD300EA48C7 /* StatusSubViewController.xib */, 34216F3E1547EBCD00EA9777 /* VideoZoomHandler.h */, 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */, + 34152079156BBEC000205A0E /* LinphoneCoreSettingsStore.h */, + 3415207A156BBEC000205A0E /* LinphoneCoreSettingsStore.m */, ); path = Classes; sourceTree = ""; @@ -1135,6 +1225,8 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( + 3415205B1563ABEB00205A0E /* MessageUI.framework */, + 34151FB61563A8D800205A0E /* InAppSettingsKit */, 340751961506459A00B89C47 /* CoreTelephony.framework */, 226CDADD14E2D0B800513B67 /* libbcg729.a */, 226CDADE14E2D0B800513B67 /* libmsbcg729.a */, @@ -1209,6 +1301,7 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 341520591563AA8F00205A0E /* 20-gear2.png */, 3485649D152C423F003FE041 /* in_call_video.png */, 3485649E152C423F003FE041 /* out_call_video.png */, 34A6ECEA14CF13CB00460C04 /* icone-linphone-72.png */, @@ -1272,6 +1365,82 @@ name = Frameworks; sourceTree = ""; }; + 34151FB61563A8D800205A0E /* InAppSettingsKit */ = { + isa = PBXGroup; + children = ( + 34151FB71563A8D800205A0E /* Controllers */, + 34151FBF1563A8D800205A0E /* Models */, + 34151FCA1563A8D800205A0E /* Views */, + 34151FD91563A8D800205A0E /* Xibs */, + ); + path = InAppSettingsKit; + sourceTree = ""; + }; + 34151FB71563A8D800205A0E /* Controllers */ = { + isa = PBXGroup; + children = ( + 34151FB81563A8D800205A0E /* IASKAppSettingsViewController.h */, + 34151FB91563A8D800205A0E /* IASKAppSettingsViewController.m */, + 34151FBA1563A8D800205A0E /* IASKAppSettingsWebViewController.h */, + 34151FBB1563A8D800205A0E /* IASKAppSettingsWebViewController.m */, + 34151FBC1563A8D800205A0E /* IASKSpecifierValuesViewController.h */, + 34151FBD1563A8D800205A0E /* IASKSpecifierValuesViewController.m */, + 34151FBE1563A8D800205A0E /* IASKViewController.h */, + ); + path = Controllers; + sourceTree = ""; + }; + 34151FBF1563A8D800205A0E /* Models */ = { + isa = PBXGroup; + children = ( + 34151FC01563A8D800205A0E /* IASKSettingsReader.h */, + 34151FC11563A8D800205A0E /* IASKSettingsReader.m */, + 34151FC21563A8D800205A0E /* IASKSettingsStore.h */, + 34151FC31563A8D800205A0E /* IASKSettingsStore.m */, + 34151FC41563A8D800205A0E /* IASKSettingsStoreFile.h */, + 34151FC51563A8D800205A0E /* IASKSettingsStoreFile.m */, + 34151FC61563A8D800205A0E /* IASKSettingsStoreUserDefaults.h */, + 34151FC71563A8D800205A0E /* IASKSettingsStoreUserDefaults.m */, + 34151FC81563A8D800205A0E /* IASKSpecifier.h */, + 34151FC91563A8D800205A0E /* IASKSpecifier.m */, + ); + path = Models; + sourceTree = ""; + }; + 34151FCA1563A8D800205A0E /* Views */ = { + isa = PBXGroup; + children = ( + 34151FCB1563A8D800205A0E /* IASKPSSliderSpecifierViewCell.h */, + 34151FCC1563A8D800205A0E /* IASKPSSliderSpecifierViewCell.m */, + 34151FCD1563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.h */, + 34151FCE1563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.m */, + 34151FCF1563A8D800205A0E /* IASKPSTitleValueSpecifierViewCell.h */, + 34151FD01563A8D800205A0E /* IASKPSTitleValueSpecifierViewCell.m */, + 34151FD11563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.h */, + 34151FD21563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.m */, + 34151FD31563A8D800205A0E /* IASKSlider.h */, + 34151FD41563A8D800205A0E /* IASKSlider.m */, + 34151FD51563A8D800205A0E /* IASKSwitch.h */, + 34151FD61563A8D800205A0E /* IASKSwitch.m */, + 34151FD71563A8D800205A0E /* IASKTextField.h */, + 34151FD81563A8D800205A0E /* IASKTextField.m */, + ); + path = Views; + sourceTree = ""; + }; + 34151FD91563A8D800205A0E /* Xibs */ = { + isa = PBXGroup; + children = ( + 34151FDA1563A8D800205A0E /* IASKAppSettingsView.xib */, + 34151FDB1563A8D800205A0E /* IASKAppSettingsWebView.xib */, + 34151FDC1563A8D800205A0E /* IASKPSSliderSpecifierViewCell.xib */, + 34151FDD1563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.xib */, + 34151FDE1563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.xib */, + 34151FDF1563A8D800205A0E /* IASKSpecifierValuesView.xib */, + ); + path = Xibs; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1413,6 +1582,13 @@ 34A6ECEB14CF13CB00460C04 /* icone-linphone-72.png in Resources */, 3485649F152C423F003FE041 /* in_call_video.png in Resources */, 348564A0152C423F003FE041 /* out_call_video.png in Resources */, + 34151FEF1563A8D800205A0E /* IASKAppSettingsView.xib in Resources */, + 34151FF01563A8D800205A0E /* IASKAppSettingsWebView.xib in Resources */, + 34151FF11563A8D800205A0E /* IASKPSSliderSpecifierViewCell.xib in Resources */, + 34151FF21563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.xib in Resources */, + 34151FF31563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.xib in Resources */, + 34151FF41563A8D800205A0E /* IASKSpecifierValuesView.xib in Resources */, + 3415205A1563AA8F00205A0E /* 20-gear2.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1483,6 +1659,12 @@ 3418845D14C7077400EA48C7 /* status_gray.png in Resources */, 57282931154AF1460076F540 /* history-orange.png in Resources */, 57282933154AF14D0076F540 /* dialer-orange.png in Resources */, + 341520051563A93B00205A0E /* IASKAppSettingsView.xib in Resources */, + 341520061563A93B00205A0E /* IASKAppSettingsWebView.xib in Resources */, + 341520071563A93B00205A0E /* IASKPSSliderSpecifierViewCell.xib in Resources */, + 341520081563A93B00205A0E /* IASKPSTextFieldSpecifierViewCell.xib in Resources */, + 341520091563A93B00205A0E /* IASKPSToggleSwitchSpecifierViewCell.xib in Resources */, + 3415200A1563A93B00205A0E /* IASKSpecifierValuesView.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1522,6 +1704,22 @@ 3418844814C6CAD300EA48C7 /* StatusSubViewController.m in Sources */, 340751E7150F38FD00B89C47 /* UIToggleVideoButton.m in Sources */, 34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */, + 34151FE01563A8D800205A0E /* IASKAppSettingsViewController.m in Sources */, + 34151FE11563A8D800205A0E /* IASKAppSettingsWebViewController.m in Sources */, + 34151FE21563A8D800205A0E /* IASKSpecifierValuesViewController.m in Sources */, + 34151FE31563A8D800205A0E /* IASKSettingsReader.m in Sources */, + 34151FE41563A8D800205A0E /* IASKSettingsStore.m in Sources */, + 34151FE51563A8D800205A0E /* IASKSettingsStoreFile.m in Sources */, + 34151FE61563A8D800205A0E /* IASKSettingsStoreUserDefaults.m in Sources */, + 34151FE71563A8D800205A0E /* IASKSpecifier.m in Sources */, + 34151FE81563A8D800205A0E /* IASKPSSliderSpecifierViewCell.m in Sources */, + 34151FE91563A8D800205A0E /* IASKPSTextFieldSpecifierViewCell.m in Sources */, + 34151FEA1563A8D800205A0E /* IASKPSTitleValueSpecifierViewCell.m in Sources */, + 34151FEB1563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.m in Sources */, + 34151FEC1563A8D800205A0E /* IASKSlider.m in Sources */, + 34151FED1563A8D800205A0E /* IASKSwitch.m in Sources */, + 34151FEE1563A8D800205A0E /* IASKTextField.m in Sources */, + 3415207B156BBEC000205A0E /* LinphoneCoreSettingsStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1558,6 +1756,22 @@ 3418844914C6CAD300EA48C7 /* StatusSubViewController.m in Sources */, 340751E8150F38FD00B89C47 /* UIToggleVideoButton.m in Sources */, 34216F411547EBCD00EA9777 /* VideoZoomHandler.m in Sources */, + 34151FF61563A92100205A0E /* IASKAppSettingsViewController.m in Sources */, + 34151FF71563A92100205A0E /* IASKAppSettingsWebViewController.m in Sources */, + 34151FF81563A92100205A0E /* IASKSpecifierValuesViewController.m in Sources */, + 34151FF91563A92900205A0E /* IASKSettingsReader.m in Sources */, + 34151FFA1563A92900205A0E /* IASKSettingsStore.m in Sources */, + 34151FFB1563A92900205A0E /* IASKSettingsStoreFile.m in Sources */, + 34151FFC1563A92900205A0E /* IASKSettingsStoreUserDefaults.m in Sources */, + 34151FFD1563A92900205A0E /* IASKSpecifier.m in Sources */, + 34151FFE1563A93400205A0E /* IASKPSSliderSpecifierViewCell.m in Sources */, + 34151FFF1563A93400205A0E /* IASKPSTextFieldSpecifierViewCell.m in Sources */, + 341520001563A93400205A0E /* IASKPSTitleValueSpecifierViewCell.m in Sources */, + 341520011563A93400205A0E /* IASKPSToggleSwitchSpecifierViewCell.m in Sources */, + 341520021563A93400205A0E /* IASKSlider.m in Sources */, + 341520031563A93400205A0E /* IASKSwitch.m in Sources */, + 341520041563A93400205A0E /* IASKTextField.m in Sources */, + 3415207C156BBEC000205A0E /* LinphoneCoreSettingsStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/submodules/linphone b/submodules/linphone index 04fa4d457..d0ced93c2 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 04fa4d457b3b584eae8c5964a48a97ec4040c94a +Subproject commit d0ced93c25f088c04a9f92b82aa41c5b1f271e23 From 4b37e1c1fe8bd7f3006039d58ac80e99e81112f0 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 1 Jun 2012 11:52:54 +0200 Subject: [PATCH 2/8] Added comments: linphone_core functions matching preferences --- Classes/LinphoneCoreSettingsStore.m | 23 +++++++++++++++++++---- Resources/20-gear2.png | Bin 0 -> 375 bytes 2 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 Resources/20-gear2.png diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index f9f9d8f62..2b40a05c1 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -8,19 +8,25 @@ #import "LinphoneCoreSettingsStore.h" - +// linphone_core_enable_logs_with_cb - linphone_core_disable_logs debugenable_preference + +// on change: edit/create linphone_core_get_default_proxy() transport_preference username_preference domain_preference password_preference -check_config_disable_preference outbound_proxy_preference proxy_preference prefix_preference substitute_+_by_00_preference -wifi_only_preference +// app internal setting +check_config_disable_preference +wifi_only_preference +backgroundmode_preference + +// linphone_core_enable_payload_type silk_24k_preference speex_16k_preference speex_8k_preference @@ -33,15 +39,24 @@ pcma_preference g722_preferenceg g729_preference +// linphone_core_enable_payload_type mp4v-es_preference h264_preference vp8_preference +// linphone_core_enable_video enable_video_preference + +// linphone_core_set_media_encryption enable_srtp_preference + +// linphone_core_set_stun_server +// linphone_core_set_firewall_policy stun_preference + +// linphone_core_set_video_policy start_video_preference -backgroundmode_preference + @implementation LinphoneCoreSettingsStore diff --git a/Resources/20-gear2.png b/Resources/20-gear2.png new file mode 100644 index 0000000000000000000000000000000000000000..b8180ded27c10b0e80bbcf5bb5e598da968b65d0 GIT binary patch literal 375 zcmV--0f_#IP)17w7B1CLN9 zg$+6a-2gU#4Z;RAk(|o1^0^|QS~`IP{w{XXGGs;g28Ou}&vMnX9xf=!7EDb>ZooxND58rOIdB7s1V znDAiPif&{!G|T>Bu_pF(A^J-G?P9@Vdm^RTqiA5ONo(;APzU&)q7EX|UE2(owRiP_ zt$qaguG`pVI(<&q&G-*(hVATY;)%!x1HlaoXro9lI=J8UmKo+K3sI;@0@SuANq42) z=;?rhOEc85>ZlW@Cyx7oeu(T5r!?4p+M)Va)D< Date: Thu, 7 Jun 2012 22:21:33 +0200 Subject: [PATCH 3/8] work in progress for in app settings --- Classes/LinphoneAppDelegate.m | 2 + Classes/LinphoneCoreSettingsStore.h | 6 + Classes/LinphoneCoreSettingsStore.m | 194 +++++++++++++++++++++++++-- Classes/LinphoneUI/LinphoneManager.m | 13 +- Settings.bundle/Advanced.plist | 40 ++++-- Settings.bundle/Root.plist | 2 - linphone.xcodeproj/project.pbxproj | 30 +---- submodules/externals/exosip | 2 +- submodules/linphone | 2 +- 9 files changed, 234 insertions(+), 57 deletions(-) diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 3807085f7..f2e8586d7 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -28,6 +28,7 @@ #import "ConsoleViewController.h" #import "MoreViewController.h" #include "CallHistoryTableViewController.h" +#import "LinphoneCoreSettingsStore.h" #include "LinphoneManager.h" #include "linphonecore.h" @@ -239,6 +240,7 @@ int __aeabi_idiv(int a, int b) { // Settings, setup delegate settingsController.delegate = [LinphoneManager instance]; settingsController.settingsReader.delegate = [LinphoneManager instance]; + settingsController.settingsStore=[[LinphoneCoreSettingsStore alloc] init]; [settingsController.settingsReader init]; diff --git a/Classes/LinphoneCoreSettingsStore.h b/Classes/LinphoneCoreSettingsStore.h index bb9df882a..95d04546a 100644 --- a/Classes/LinphoneCoreSettingsStore.h +++ b/Classes/LinphoneCoreSettingsStore.h @@ -9,7 +9,13 @@ #import #import "IASKSettingsStore.h" +#import "LinphoneManager.h" + @interface LinphoneCoreSettingsStore : IASKAbstractSettingsStore { + NSDictionary *dict; } +- (void) enableCodecWithName: (const char*) name andRate: (int) rate to:(id)value; +-(void) transformLinphoneCoreToKeys; + @end diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index 2b40a05c1..370d9323f 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -8,6 +8,10 @@ #import "LinphoneCoreSettingsStore.h" +#include "lpconfig.h" + + +#if 0 // linphone_core_enable_logs_with_cb - linphone_core_disable_logs debugenable_preference @@ -18,8 +22,8 @@ domain_preference password_preference outbound_proxy_preference proxy_preference -prefix_preference -substitute_+_by_00_preference +prefix_preference ++ +substitute_+_by_00_preference ++ // app internal setting check_config_disable_preference @@ -36,7 +40,7 @@ gsm_8k_preference ilbc_preference pcmu_preference pcma_preference -g722_preferenceg +g722_preference g729_preference // linphone_core_enable_payload_type @@ -46,6 +50,8 @@ vp8_preference // linphone_core_enable_video enable_video_preference +// linphone_core_set_video_policy +start_video_preference // linphone_core_set_media_encryption enable_srtp_preference @@ -54,23 +60,195 @@ enable_srtp_preference // linphone_core_set_firewall_policy stun_preference -// linphone_core_set_video_policy -start_video_preference +#endif + +struct codec_name_pref_table{ + const char *name; + int rate; + NSString *prefname; +}; + +struct codec_name_pref_table codec_pref_table[]={ + { "speex", 8000, @"speex_8k_preference" }, + { "speex", 16000, @"speex_16k_preference" }, + { "silk", 24000, @"silk_24k_preference" }, + { "silk", 16000, @"silk_16k_preference" }, + { "amr", 8000, @"amr_8k_preference" }, + { "ilbc", 8000, @"ilbc_preference"}, + { "pcmu", 8000, @"pcmu_preference"}, + { "pcma", 8000, @"pcma_preference"}, + { "g722", 8000, @"g722_preference"}, + { "g729", 8000, @"g729_preference"}, + { "mp4v-es", 90000, @"mp4v-es_preference"}, + { "h264", 90000, @"h264_preference"}, + { "vp8", 90000, @"vp8_preference"}, + { NULL,0,Nil } +}; + +static NSString *getPrefForCodec(const char *name, int rate){ + int i; + for(i=0;codec_pref_table[i].name!=NULL;++i){ + if (strcasecmp(codec_pref_table[i].name,name)==0 && codec_pref_table[i].rate==rate) + return codec_pref_table[i].prefname; + } + return Nil; +} + @implementation LinphoneCoreSettingsStore +-(id) init{ + self = [super init]; + if (self){ + dict=[[NSMutableDictionary alloc] init]; + [self transformLinphoneCoreToKeys]; + } + return self; +} + +-(void) dealloc{ + [super dealloc]; + [dict release]; +} + +-(void) transformKeysToLinphoneCore{ + //LinphoneCore *lc=[LinphoneManager getLc]; + +} + +- (void) setString:(const char*)value forKey:(NSString*)key{ + id obj=Nil; + if (value) obj=[[NSString alloc] initWithCString:value encoding:[NSString defaultCStringEncoding] ]; + [self setObject: obj forKey:key]; +} + +-(void) transformCodecsToKeys: (const MSList *)codecs{ + LinphoneCore *lc=[LinphoneManager getLc]; + const MSList *elem=codecs; + for(;elem!=NULL;elem=elem->next){ + PayloadType *pt=(PayloadType*)elem->data; + NSString *pref=getPrefForCodec(pt->mime_type,pt->clock_rate); + if (pref){ + [self setBool: linphone_core_payload_type_enabled(lc,pt) forKey: pref]; + }else{ + ms_warning("Codec %s/%i supported by core is not shown in iOS app config view.", + pt->mime_type,pt->clock_rate); + } + } +} + +-(void) transformLinphoneCoreToKeys{ + LinphoneCore *lc=[LinphoneManager getLc]; + LinphoneProxyConfig *cfg=NULL; + linphone_core_get_default_proxy(lc,&cfg); + if (cfg){ + const char *identity=linphone_proxy_config_get_identity(cfg); + LinphoneAddress *addr=linphone_address_new(identity); + if (addr){ + const char *proxy=linphone_proxy_config_get_addr(cfg); + LinphoneAddress *proxy_addr=linphone_address_new(proxy); + const char *port=linphone_address_get_port(proxy_addr); + + [self setString: linphone_address_get_username(addr) forKey:@"username_preference"]; + [self setString: linphone_address_get_domain(addr) forKey:@"domain_preference"]; + if (strcmp(linphone_address_get_domain(addr),linphone_address_get_domain(proxy_addr))!=0 + || port!=NULL){ + char tmp[256]={0}; + if (port!=NULL) { + snprintf(tmp,sizeof(tmp)-1,"%s:%s",linphone_address_get_domain(proxy_addr),port); + }else snprintf(tmp,sizeof(tmp)-1,"%s",linphone_address_get_domain(proxy_addr)); + [self setString: tmp forKey:@"proxy_preference"]; + } + linphone_address_destroy(addr); + linphone_address_destroy(proxy_addr); + + [self setBool: (linphone_proxy_config_get_route(cfg)!=NULL) forKey:@"outbound_proxy_preference"]; + + } + } + { + LCSipTransports tp; + const char *tname="udp"; + linphone_core_get_sip_transports(lc, &tp); + if (tp.udp_port>0) tname="udp"; + else if (tp.tcp_port>0) tname="tcp"; + else if (tp.tls_port>0) tname="tls"; + [self setString: tname forKey:@"transport_preference"]; + } + { + LinphoneAuthInfo *ai; + const MSList *elem=linphone_core_get_auth_info_list(lc); + if (elem && (ai=(LinphoneAuthInfo*)elem->data)){ + [self setString: linphone_auth_info_get_passwd(ai) forKey:@"password_preference"]; + } + } + { + [self setString: linphone_core_get_stun_server(lc) forKey:@"stun_preference"]; + } + + { + [self transformCodecsToKeys: linphone_core_get_audio_codecs(lc)]; + [self transformCodecsToKeys: linphone_core_get_video_codecs(lc)]; + } + + { + LinphoneMediaEncryption menc=linphone_core_get_media_encryption(lc); + const char *val; + switch(menc){ + LinphoneMediaEncryptionSRTP: + val="SRTP"; + break; + LinphoneMediaEncryptionZRTP: + val="ZRTP"; + break; + default: + val="None"; + } + [self setString:val forKey:@"media_encryption_preference"]; + } + + [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","debugenable_preference",0) forKey:@"debugenable_preference"]; + [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","check_config_disable_preference",0) forKey:@"check_config_disable_preference"]; + [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","wifi_only_preference",0) forKey:@"wifi_only_preference"]; + [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","backgroundmode_preference",TRUE) forKey:@"backgroundmode_preference"]; + [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","start_at_boot_preference",TRUE) forKey:@"disable_autoboot_preference"]; + + if (linphone_core_tunnel_available()){ + /*FIXME: enhance linphonecore API to handle tunnel more easily in applications */ + LinphoneTunnel *tun=linphone_core_get_tunnel(lc); + //[self setString: linphone_tunnel_get_servers(tun) forKey:tunnel_address_preference]; + //[self setInteger: blabla forKey:tunnel_port_preference]; + //[self setString: forKey:@"tunnel_enabled_preference"]; + } + { + const LinphoneVideoPolicy *pol; + [self setBool: linphone_core_video_enabled(lc) forKey:@"enable_video_preference"]; + pol=linphone_core_get_video_policy(lc); + [self setBool:(pol->automatically_accept && pol->automatically_initiate) forKey:@"start_video_preference"]; + } +} -(void) setObject:(id)value forKey:(NSString *)key { - - + [dict setValue:value forKey:key]; } - (id)objectForKey:(NSString*)key { - return nil; + return [dict valueForKey:key]; } + - (BOOL)synchronize { + ms_message("Called in SettingsStore synchronize"); return YES; } +- (void) enableCodecWithName: (const char*) name andRate: (int) rate to:(id)value{ + LinphoneCore *lc=[LinphoneManager getLc]; + PayloadType *pt; + pt=linphone_core_find_payload_type(lc, name, rate); + if (pt){ + linphone_core_enable_payload_type(lc, pt, [value boolValue]); + } +} + @end diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index 50a632aee..2188d73c6 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -998,15 +998,14 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach //go directly to bg mode [self enterBackgroundMode]; } + NSUInteger cpucount = [[NSProcessInfo processInfo] processorCount]; + ms_set_cpu_count(cpucount); + - if ([LinphoneManager runningOnIpad]) - ms_set_cpu_count(2); - else - ms_set_cpu_count(1); - - ms_warning("Linphone [%s] started on [%s]" + ms_warning("Linphone [%s] started on [%s], running with [%u] processor(s)" ,linphone_core_get_version() - ,[[UIDevice currentDevice].model cStringUsingEncoding:[NSString defaultCStringEncoding]] ); + ,[[UIDevice currentDevice].model cStringUsingEncoding:[NSString defaultCStringEncoding]], + cpucount); } diff --git a/Settings.bundle/Advanced.plist b/Settings.bundle/Advanced.plist index c0c81b34a..bfe884eb2 100644 --- a/Settings.bundle/Advanced.plist +++ b/Settings.bundle/Advanced.plist @@ -58,13 +58,13 @@ DefaultValue - - Key - wifi_only_preference - Title - Wifi only - Type - PSToggleSwitchSpecifier + + Key + wifi_only_preference + Title + Wifi only + Type + PSToggleSwitchSpecifier DefaultValue @@ -90,21 +90,33 @@ DefaultValue - + None Key - enable_srtp_preference + media_encryption_preference Title - Secure rtp + Media Encryption + Titles + + None + SRTP + ZRTP + Type - PSToggleSwitchSpecifier + PSMultiValueSpecifier + Values + + None + SRTP + ZRTP + DefaultValue - + Key - disable_autoboot_preference + start_at_boot_preference Title - Disable application autostart + Start at boot Type PSToggleSwitchSpecifier diff --git a/Settings.bundle/Root.plist b/Settings.bundle/Root.plist index bd5c9216c..f2aa11c6c 100644 --- a/Settings.bundle/Root.plist +++ b/Settings.bundle/Root.plist @@ -9,8 +9,6 @@ SIP account Type PSGroupSpecifier - FooterText - Linphone must be restarted for changes to take effect AutocapitalizationType diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 806364d34..81e6e686e 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -29,7 +29,6 @@ 220FAD3810765B400068D98F /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2F10765B400068D98F /* libspeex.a */; }; 220FAD3910765B400068D98F /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD3010765B400068D98F /* libspeexdsp.a */; }; 220FAE4B10767A6A0068D98F /* PhoneMainView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 220FAE4A10767A6A0068D98F /* PhoneMainView.xib */; }; - 2211DB95147564B400DEE054 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2211DB94147564B400DEE054 /* Settings.bundle */; }; 2211DBBE14769C8300DEE054 /* CallDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2211DBBB14769C8200DEE054 /* CallDelegate.m */; }; 2211DBBF14769C8300DEE054 /* CallDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2211DBBB14769C8200DEE054 /* CallDelegate.m */; }; 2211DBC014769CB200DEE054 /* IncallViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 222A483212F7176F0075F07F /* IncallViewController.m */; }; @@ -92,7 +91,6 @@ 226183AE1472527D0037138E /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AB1472527D0037138E /* libsrtp.a */; }; 226183B0147259670037138E /* libmssilk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AF147259670037138E /* libmssilk.a */; }; 2264B6D211200342002C2C53 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2264B6D111200342002C2C53 /* SystemConfiguration.framework */; }; - 226B563F13CAF1CD00921595 /* audio.plist in Resources */ = {isa = PBXBuildFile; fileRef = 226B563E13CAF1CD00921595 /* audio.plist */; }; 226CDADF14E2D0B800513B67 /* libbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226CDADD14E2D0B800513B67 /* libbcg729.a */; }; 226CDAE014E2D0B800513B67 /* libmsbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226CDADE14E2D0B800513B67 /* libmsbcg729.a */; }; 226F2ED61344B0EF00F6EF27 /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED31344B0EF00F6EF27 /* libopencore-amrwb.a */; }; @@ -142,8 +140,6 @@ 22D8F13D147548E2008C97DB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2214783B1386A2030020F8B8 /* Localizable.strings */; }; 22D8F13E147548E2008C97DB /* missed_call.png in Resources */ = {isa = PBXBuildFile; fileRef = 22E19E47138A67A000FBFE87 /* missed_call.png */; }; 22D8F13F147548E2008C97DB /* VideoViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 22E028B613B4CCBD0068A713 /* VideoViewController.xib */; }; - 22D8F140147548E2008C97DB /* audio.plist in Resources */ = {isa = PBXBuildFile; fileRef = 226B563E13CAF1CD00921595 /* audio.plist */; }; - 22D8F141147548E2008C97DB /* video.plist in Resources */ = {isa = PBXBuildFile; fileRef = 22E1A9E713CAF4AA00219531 /* video.plist */; }; 22D8F142147548E2008C97DB /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 70571E1913FABCB000CDD3C2 /* rootca.pem */; }; 22D8F144147548E2008C97DB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 22D8F145147548E2008C97DB /* LinphoneAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */; }; @@ -206,7 +202,6 @@ 22E0A823111C44E100B04932 /* ConsoleViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 22E0A81E111C44E100B04932 /* ConsoleViewController.xib */; }; 22E0A824111C44E100B04932 /* ConsoleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22E0A81F111C44E100B04932 /* ConsoleViewController.m */; }; 22E19E48138A67A000FBFE87 /* missed_call.png in Resources */ = {isa = PBXBuildFile; fileRef = 22E19E47138A67A000FBFE87 /* missed_call.png */; }; - 22E1A9E813CAF4AA00219531 /* video.plist in Resources */ = {isa = PBXBuildFile; fileRef = 22E1A9E713CAF4AA00219531 /* video.plist */; }; 22E5B0AF133B5EA20044EA25 /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22E5B0AD133B5EA20044EA25 /* libssl.a */; }; 22E5B0B0133B5EA20044EA25 /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22E5B0AE133B5EA20044EA25 /* libcrypto.a */; }; 22F2508E107141E100AC9B3F /* PhoneViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22F2508C107141E100AC9B3F /* PhoneViewController.m */; }; @@ -316,6 +311,8 @@ 34CA853A148F692A00503C01 /* MainScreenWithVideoPreview.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CA8538148F692A00503C01 /* MainScreenWithVideoPreview.m */; }; 57282931154AF1460076F540 /* history-orange.png in Resources */ = {isa = PBXBuildFile; fileRef = 34C7646B14CD5585008E9607 /* history-orange.png */; }; 57282933154AF14D0076F540 /* dialer-orange.png in Resources */ = {isa = PBXBuildFile; fileRef = 34C7646A14CD5585008E9607 /* dialer-orange.png */; }; + 57D2B457157E4580002EA69B /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3415205B1563ABEB00205A0E /* MessageUI.framework */; }; + 57D2B45B1580FF58002EA69B /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 57D2B45A1580FF58002EA69B /* Settings.bundle */; }; 70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 70571E1913FABCB000CDD3C2 /* rootca.pem */; }; 7066FC0C13E830E400EFC6DC /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0B13E830E400EFC6DC /* libvpx.a */; }; 70E542F313E147E3002BA2C0 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F213E147E3002BA2C0 /* OpenGLES.framework */; }; @@ -474,7 +471,6 @@ 220FAE4A10767A6A0068D98F /* PhoneMainView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PhoneMainView.xib; sourceTree = ""; }; 2211DB8F147555C800DEE054 /* libmediastreamer.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmediastreamer.a; path = "liblinphone-sdk/apple-darwin/lib/libmediastreamer.a"; sourceTree = ""; }; 2211DB911475562600DEE054 /* liblinphone.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblinphone.a; path = "liblinphone-sdk/apple-darwin/lib/liblinphone.a"; sourceTree = ""; }; - 2211DB94147564B400DEE054 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Settings.bundle; path = "nogpl-thirdparties/Settings.bundle"; sourceTree = ""; }; 2211DBBB14769C8200DEE054 /* CallDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallDelegate.m; sourceTree = ""; }; 2211DBCA1476BE7300DEE054 /* ajouter.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ajouter.png; path = Resources/ajouter.png; sourceTree = ""; }; 2211DBCB1476BE7300DEE054 /* clavier.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = clavier.png; path = Resources/clavier.png; sourceTree = ""; }; @@ -537,7 +533,6 @@ 226183AB1472527D0037138E /* libsrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsrtp.a; path = "liblinphone-sdk/apple-darwin/lib/libsrtp.a"; sourceTree = ""; }; 226183AF147259670037138E /* libmssilk.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmssilk.a; path = "liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmssilk.a"; sourceTree = ""; }; 2264B6D111200342002C2C53 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; - 226B563E13CAF1CD00921595 /* audio.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = audio.plist; path = Settings.bundle/audio.plist; sourceTree = ""; }; 226CDADD14E2D0B800513B67 /* libbcg729.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbcg729.a; path = "liblinphone-sdk/apple-darwin/lib/libbcg729.a"; sourceTree = ""; }; 226CDADE14E2D0B800513B67 /* libmsbcg729.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsbcg729.a; path = "liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmsbcg729.a"; sourceTree = ""; }; 226F2ED31344B0EF00F6EF27 /* libopencore-amrwb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libopencore-amrwb.a"; path = "liblinphone-sdk/apple-darwin/lib/libopencore-amrwb.a"; sourceTree = ""; }; @@ -652,7 +647,6 @@ 22E0A81F111C44E100B04932 /* ConsoleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConsoleViewController.m; sourceTree = ""; }; 22E0A820111C44E100B04932 /* ConsoleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsoleViewController.h; sourceTree = ""; }; 22E19E47138A67A000FBFE87 /* missed_call.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = missed_call.png; path = Resources/missed_call.png; sourceTree = ""; }; - 22E1A9E713CAF4AA00219531 /* video.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = video.plist; path = Settings.bundle/video.plist; sourceTree = ""; }; 22E5B0AD133B5EA20044EA25 /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libssl.a; path = "liblinphone-sdk/apple-darwin/lib/libssl.a"; sourceTree = ""; }; 22E5B0AE133B5EA20044EA25 /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcrypto.a; path = "liblinphone-sdk/apple-darwin/lib/libcrypto.a"; sourceTree = ""; }; 22F2508B107141E100AC9B3F /* PhoneViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhoneViewController.h; sourceTree = ""; }; @@ -742,6 +736,7 @@ 34CA8534148F669900503C01 /* VideoViewController-ipad.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "VideoViewController-ipad.xib"; sourceTree = ""; }; 34CA8537148F692A00503C01 /* MainScreenWithVideoPreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainScreenWithVideoPreview.h; sourceTree = ""; }; 34CA8538148F692A00503C01 /* MainScreenWithVideoPreview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainScreenWithVideoPreview.m; sourceTree = ""; }; + 57D2B45A1580FF58002EA69B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 70571E1913FABCB000CDD3C2 /* rootca.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = rootca.pem; path = Resources/rootca.pem; sourceTree = ""; }; 7066FC0B13E830E400EFC6DC /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = "liblinphone-sdk/apple-darwin/lib/libvpx.a"; sourceTree = ""; }; 70E542F213E147E3002BA2C0 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; @@ -808,6 +803,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 57D2B457157E4580002EA69B /* MessageUI.framework in Frameworks */, 34075199150645A300B89C47 /* CoreTelephony.framework in Frameworks */, 22D8F15B147548E2008C97DB /* libvpx.a in Frameworks */, 22D8F15C147548E2008C97DB /* QuartzCore.framework in Frameworks */, @@ -1100,14 +1096,6 @@ path = speex; sourceTree = ""; }; - 2211DB9614764F6B00DEE054 /* nogpl-thirdparties */ = { - isa = PBXGroup; - children = ( - 2211DB94147564B400DEE054 /* Settings.bundle */, - ); - name = "nogpl-thirdparties"; - sourceTree = ""; - }; 2214EB7012F84668002A5394 /* LinphoneUI */ = { isa = PBXGroup; children = ( @@ -1225,6 +1213,7 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( + 57D2B45A1580FF58002EA69B /* Settings.bundle */, 3415205B1563ABEB00205A0E /* MessageUI.framework */, 34151FB61563A8D800205A0E /* InAppSettingsKit */, 340751961506459A00B89C47 /* CoreTelephony.framework */, @@ -1233,7 +1222,6 @@ 344ABDEF14850AE9007420B6 /* libc++.1.dylib */, 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */, 344ABDE71484E723007420B6 /* libzrtpcpp.a */, - 2211DB9614764F6B00DEE054 /* nogpl-thirdparties */, 2211DB911475562600DEE054 /* liblinphone.a */, 2211DB8F147555C800DEE054 /* libmediastreamer.a */, 226183AF147259670037138E /* libmssilk.a */, @@ -1244,8 +1232,6 @@ 70E542F213E147E3002BA2C0 /* OpenGLES.framework */, 22AA8AFB13D7125500B30535 /* libx264.a */, 22AA8AFC13D7125500B30535 /* libmsx264.a */, - 22E1A9E713CAF4AA00219531 /* video.plist */, - 226B563E13CAF1CD00921595 /* audio.plist */, 22276E8813C73DC000210156 /* CoreMedia.framework */, 22276E8613C73D8A00210156 /* CoreVideo.framework */, 22276E8013C73D3100210156 /* libavcodec.a */, @@ -1540,8 +1526,6 @@ 2214783D1386A2030020F8B8 /* Localizable.strings in Resources */, 22E19E48138A67A000FBFE87 /* missed_call.png in Resources */, 22E028B813B4CCBD0068A713 /* VideoViewController.xib in Resources */, - 226B563F13CAF1CD00921595 /* audio.plist in Resources */, - 22E1A9E813CAF4AA00219531 /* video.plist in Resources */, 70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */, 2211DBD51476BE7300DEE054 /* ajouter.png in Resources */, 2211DBD71476BE7300DEE054 /* clavier.png in Resources */, @@ -1596,6 +1580,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 57D2B45B1580FF58002EA69B /* Settings.bundle in Resources */, 22D8F11F147548E2008C97DB /* linphonerc in Resources */, 22D8F120147548E2008C97DB /* PhoneViewController.xib in Resources */, 22D8F121147548E2008C97DB /* ringback.wav in Resources */, @@ -1621,10 +1606,7 @@ 22D8F13D147548E2008C97DB /* Localizable.strings in Resources */, 22D8F13E147548E2008C97DB /* missed_call.png in Resources */, 22D8F13F147548E2008C97DB /* VideoViewController.xib in Resources */, - 22D8F140147548E2008C97DB /* audio.plist in Resources */, - 22D8F141147548E2008C97DB /* video.plist in Resources */, 22D8F142147548E2008C97DB /* rootca.pem in Resources */, - 2211DB95147564B400DEE054 /* Settings.bundle in Resources */, 2211DBD61476BE7300DEE054 /* ajouter.png in Resources */, 2211DBD81476BE7300DEE054 /* clavier.png in Resources */, 2211DBDA1476BE7300DEE054 /* contact.png in Resources */, diff --git a/submodules/externals/exosip b/submodules/externals/exosip index 014f5a021..8c42924ae 160000 --- a/submodules/externals/exosip +++ b/submodules/externals/exosip @@ -1 +1 @@ -Subproject commit 014f5a021ad4a0c024088edbb721f144a6f96699 +Subproject commit 8c42924ae9009f6003e98d29638e078ca1bd7c71 diff --git a/submodules/linphone b/submodules/linphone index d0ced93c2..bad6c152f 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit d0ced93c25f088c04a9f92b82aa41c5b1f271e23 +Subproject commit bad6c152f1521de8648d47c70e9321b7668b40b5 From 4507faf34faf3dd11b7bbe30fd978b3eb524d5ea Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Fri, 8 Jun 2012 10:57:00 +0200 Subject: [PATCH 4/8] Fix invalid view state after a transfert of outgoing call --- Classes/PhoneViewController.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PhoneViewController.m b/Classes/PhoneViewController.m index 91872a2c4..66ca69f2a 100644 --- a/Classes/PhoneViewController.m +++ b/Classes/PhoneViewController.m @@ -320,8 +320,8 @@ -(void) displayInCall: (LinphoneCall*) call FromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName { [mMainScreenWithVideoPreview showPreview:NO]; - if (self.presentedViewController != (UIViewController*)mIncallViewController && (call == 0x0 || - linphone_call_get_dir(call)==LinphoneCallIncoming)){ + if (self.presentedViewController != (UIViewController*)mIncallViewController /*&& (call == 0x0 || + linphone_call_get_dir(call)==LinphoneCallIncoming)*/){ [self presentModalViewController:(UIViewController*)mIncallViewController animated:true]; } From 3165914299e7b90a6f81427f4a962cd32572d283 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 8 Jun 2012 22:07:43 +0200 Subject: [PATCH 5/8] update ilbc codec to workaround google's failure to use correct TLS certificateson its machine. --- submodules/libilbc-rfc3951 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/libilbc-rfc3951 b/submodules/libilbc-rfc3951 index af32518af..a70714c2e 160000 --- a/submodules/libilbc-rfc3951 +++ b/submodules/libilbc-rfc3951 @@ -1 +1 @@ -Subproject commit af32518af41f97caee07070234a3475409b9a27d +Subproject commit a70714c2e8a1f6f9958450cb612e3dc9895981e7 From 2e3d4c0fdff7cc2e3db6ff5e37d8d75997b99db9 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 12 Jun 2012 00:38:34 +0200 Subject: [PATCH 6/8] many bugfixes, work in progress --- Classes/LinphoneAppDelegate.m | 6 +- Classes/LinphoneCoreSettingsStore.h | 1 - Classes/LinphoneCoreSettingsStore.m | 243 ++++++++---- Classes/LinphoneUI/LinphoneManager.h | 6 +- Classes/LinphoneUI/LinphoneManager.m | 350 +++--------------- .../IASKAppSettingsViewController.h | 3 + .../IASKAppSettingsViewController.m | 9 +- InAppSettingsKit/Models/IASKSettingsReader.h | 6 +- InAppSettingsKit/Models/IASKSettingsReader.m | 15 +- PhoneMainView.xib | 67 ++-- linphone.xcodeproj/project.pbxproj | 22 +- .../Settings.bundle/Advanced.plist | 103 ------ nogpl-thirdparties/Settings.bundle/Root.plist | 131 ------- .../Settings.bundle/audio.plist | 85 ----- .../Settings.bundle/en.lproj/Root.strings | Bin 546 -> 0 bytes .../Settings.bundle/video.plist | 45 --- .../Inappsettings.bundle}/Advanced.plist | 0 .../Inappsettings.bundle}/Root.plist | 0 .../Inappsettings.bundle}/audio.plist | 0 .../en.lproj/Root.strings | Bin .../Inappsettings.bundle}/video.plist | 0 submodules/libilbc-rfc3951 | 2 +- 22 files changed, 304 insertions(+), 790 deletions(-) delete mode 100644 nogpl-thirdparties/Settings.bundle/Advanced.plist delete mode 100644 nogpl-thirdparties/Settings.bundle/Root.plist delete mode 100644 nogpl-thirdparties/Settings.bundle/audio.plist delete mode 100644 nogpl-thirdparties/Settings.bundle/en.lproj/Root.strings delete mode 100644 nogpl-thirdparties/Settings.bundle/video.plist rename {Settings.bundle => settings/Inappsettings.bundle}/Advanced.plist (100%) rename {Settings.bundle => settings/Inappsettings.bundle}/Root.plist (100%) rename {Settings.bundle => settings/Inappsettings.bundle}/audio.plist (100%) rename {Settings.bundle => settings/Inappsettings.bundle}/en.lproj/Root.strings (100%) rename {Settings.bundle => settings/Inappsettings.bundle}/video.plist (100%) diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index f2e8586d7..f11c2a97b 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -239,9 +239,11 @@ int __aeabi_idiv(int a, int b) { // Settings, setup delegate settingsController.delegate = [LinphoneManager instance]; - settingsController.settingsReader.delegate = [LinphoneManager instance]; + settingsController.settingsReaderDelegate = [LinphoneManager instance]; settingsController.settingsStore=[[LinphoneCoreSettingsStore alloc] init]; - [settingsController.settingsReader init]; + //settingsController.file=@"settings/Inappsettings.bundle"; + settingsController.showCreditsFooter=FALSE; + //[settingsController.settingsReader init]; [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound]; diff --git a/Classes/LinphoneCoreSettingsStore.h b/Classes/LinphoneCoreSettingsStore.h index 95d04546a..af1f272c2 100644 --- a/Classes/LinphoneCoreSettingsStore.h +++ b/Classes/LinphoneCoreSettingsStore.h @@ -15,7 +15,6 @@ NSDictionary *dict; } -- (void) enableCodecWithName: (const char*) name andRate: (int) rate to:(id)value; -(void) transformLinphoneCoreToKeys; @end diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index 370d9323f..0df80d755 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -11,59 +11,6 @@ #include "lpconfig.h" -#if 0 -// linphone_core_enable_logs_with_cb - linphone_core_disable_logs -debugenable_preference - -// on change: edit/create linphone_core_get_default_proxy() -transport_preference -username_preference -domain_preference -password_preference -outbound_proxy_preference -proxy_preference -prefix_preference ++ -substitute_+_by_00_preference ++ - -// app internal setting -check_config_disable_preference -wifi_only_preference -backgroundmode_preference - -// linphone_core_enable_payload_type -silk_24k_preference -speex_16k_preference -speex_8k_preference -silk_16k_preference -amr_8k_preference -gsm_8k_preference -ilbc_preference -pcmu_preference -pcma_preference -g722_preference -g729_preference - -// linphone_core_enable_payload_type -mp4v-es_preference -h264_preference -vp8_preference - -// linphone_core_enable_video -enable_video_preference -// linphone_core_set_video_policy -start_video_preference - -// linphone_core_set_media_encryption -enable_srtp_preference - -// linphone_core_set_stun_server -// linphone_core_set_firewall_policy -stun_preference - - - -#endif - struct codec_name_pref_table{ const char *name; int rate; @@ -123,6 +70,10 @@ static NSString *getPrefForCodec(const char *name, int rate){ [self setObject: obj forKey:key]; } +- (NSString*) stringForKey:(NSString*) key{ + return [self objectForKey: key]; +} + -(void) transformCodecsToKeys: (const MSList *)codecs{ LinphoneCore *lc=[LinphoneManager getLc]; const MSList *elem=codecs; @@ -231,6 +182,9 @@ static NSString *getPrefForCodec(const char *name, int rate){ -(void) setObject:(id)value forKey:(NSString *)key { [dict setValue:value forKey:key]; + NSString *changed_value=[[NSString alloc] initWithFormat:@"%@_changed", key]; + [dict setValue:[NSNumber numberWithBool:TRUE] forKey:changed_value]; + [changed_value release]; } - (id)objectForKey:(NSString*)key { @@ -238,17 +192,180 @@ static NSString *getPrefForCodec(const char *name, int rate){ } - (BOOL)synchronize { - ms_message("Called in SettingsStore synchronize"); + LinphoneCore *lc=[LinphoneManager getLc]; + LinphoneManager* lLinphoneMgr = [LinphoneManager instance]; + + NSLog(@"Called in SettingsStore synchronize"); + if ([self boolForKey:@"username_preference_changed"]) + NSLog(@"username_preference_changed !!"); + return YES; + /* unregister before modifying any settings */ + { + LinphoneProxyConfig* proxyCfg; + linphone_core_get_default_proxy(lc, &proxyCfg); + + if (proxyCfg) { + // this will force unregister WITHOUT destorying the proxyCfg object + linphone_proxy_config_edit(proxyCfg); + + int i=0; + while (linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationNone && + linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationCleared && + linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationFailed && + i++<40 ) { + linphone_core_iterate(lc); + usleep(10000); + } + } + } + + NSString* transport = [self stringForKey:@"transport_preference"]; + + LCSipTransports transportValue; + if (transport!=nil) { + if (linphone_core_get_sip_transports(lc, &transportValue)) { + ms_error("cannot get current transport"); + } + // Only one port can be set at one time, the others's value is 0 + if ([transport isEqualToString:@"tcp"]) { + if (transportValue.tcp_port == 0) transportValue.tcp_port=transportValue.udp_port + transportValue.tls_port; + transportValue.udp_port=0; + transportValue.tls_port=0; + } else if ([transport isEqualToString:@"udp"]){ + if (transportValue.udp_port == 0) transportValue.udp_port=transportValue.tcp_port + transportValue.tls_port; + transportValue.tcp_port=0; + transportValue.tls_port=0; + } else if ([transport isEqualToString:@"tls"]){ + if (transportValue.tls_port == 0) transportValue.tls_port=transportValue.udp_port + transportValue.tcp_port; + transportValue.tcp_port=0; + transportValue.udp_port=0; + } else { + ms_error("unexpected transport [%s]",[transport cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } + if (linphone_core_set_sip_transports(lc, &transportValue)) { + ms_error("cannot set transport"); + } + } + + + //configure sip account + + //mandatory parameters + + NSString* username = [self stringForKey:@"username_preference"]; + NSString* domain = [self stringForKey:@"domain_preference"]; + NSString* accountPassword = [self stringForKey:@"password_preference"]; + bool isOutboundProxy= [self boolForKey:@"outbound_proxy_preference"]; + + + //clear auth info list + linphone_core_clear_all_auth_info(lc); + //clear existing proxy config + linphone_core_clear_proxy_config(lc); + if (username && [username length] >0 && domain && [domain length]>0) { + const char* identity = [[NSString stringWithFormat:@"sip:%@@%@",username,domain] cStringUsingEncoding:[NSString defaultCStringEncoding]]; + const char* password = [accountPassword cStringUsingEncoding:[NSString defaultCStringEncoding]]; + + NSString* proxyAddress = [[NSUserDefaults standardUserDefaults] stringForKey:@"proxy_preference"]; + if ((!proxyAddress || [proxyAddress length] <1 ) && domain) { + proxyAddress = [NSString stringWithFormat:@"sip:%@",domain] ; + } else { + proxyAddress = [NSString stringWithFormat:@"sip:%@",proxyAddress] ; + } + + const char* proxy = [proxyAddress cStringUsingEncoding:[NSString defaultCStringEncoding]]; + + NSString* prefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"prefix_preference"]; + bool substitute_plus_by_00 = [[NSUserDefaults standardUserDefaults] boolForKey:@"substitute_+_by_00_preference"]; + //possible valid config detected + LinphoneProxyConfig* proxyCfg; + proxyCfg = linphone_proxy_config_new(); + + // add username password + LinphoneAddress *from = linphone_address_new(identity); + LinphoneAuthInfo *info; + if (from !=0){ + info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL); + linphone_core_add_auth_info(lc,info); + } + linphone_address_destroy(from); + + // configure proxy entries + linphone_proxy_config_set_identity(proxyCfg,identity); + linphone_proxy_config_set_server_addr(proxyCfg,proxy); + linphone_proxy_config_enable_register(proxyCfg,true); + BOOL isWifiOnly = [self boolForKey:@"wifi_only_preference"]; + + if (isWifiOnly && lLinphoneMgr.connectivity == wwan) { + linphone_proxy_config_expires(proxyCfg, 0); + } else { + linphone_proxy_config_expires(proxyCfg, lLinphoneMgr.defaultExpires); + } + + if (isOutboundProxy) + linphone_proxy_config_set_route(proxyCfg,proxy); + + if ([prefix length]>0) { + linphone_proxy_config_set_dial_prefix(proxyCfg, [prefix cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } + linphone_proxy_config_set_dial_escape_plus(proxyCfg,substitute_plus_by_00); + + linphone_core_add_proxy_config(lc,proxyCfg); + //set to default proxy + linphone_core_set_default_proxy(lc,proxyCfg); + + } + + //Configure Codecs + + PayloadType *pt; + const MSList *elem; + //disable all codecs + for (elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){ + pt=(PayloadType*)elem->data; + linphone_core_enable_payload_type(lc,pt,[self boolForKey: getPrefForCodec(pt->mime_type,pt->clock_rate)]); + } + for (elem=linphone_core_get_video_codecs(lc);elem!=NULL;elem=elem->next){ + pt=(PayloadType*)elem->data; + linphone_core_enable_payload_type(lc,pt,[self boolForKey: getPrefForCodec(pt->mime_type,pt->clock_rate)]); + } + + bool enableVideo = [self boolForKey:@"enable_video_preference"]; + linphone_core_enable_video(lc, enableVideo, enableVideo); + + NSString *menc = [self stringForKey:@"media_encryption_preference"]; + if (menc && [menc compare:@"SRTP"]) + linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionSRTP); + else if (menc && [menc compare:@"ZRTP"]) + linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionZRTP); + else linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionNone); + + NSString* stun_server = [self stringForKey:@"stun_preference"]; + if ([stun_server length]>0){ + linphone_core_set_stun_server(lc,[stun_server cStringUsingEncoding:[NSString defaultCStringEncoding]]); + linphone_core_set_firewall_policy(lc, LinphonePolicyUseStun); + }else{ + linphone_core_set_stun_server(lc, NULL); + linphone_core_set_firewall_policy(lc, LinphonePolicyNoFirewall); + } + + LinphoneVideoPolicy policy; + policy.automatically_accept = [self boolForKey:@"start_video_preference"];; + policy.automatically_initiate = [self boolForKey:@"start_video_preference"]; + linphone_core_set_video_policy(lc, &policy); + + UIDevice* device = [UIDevice currentDevice]; + bool backgroundSupported = false; + if ([device respondsToSelector:@selector(isMultitaskingSupported)]) + backgroundSupported = [device isMultitaskingSupported]; + BOOL isbackgroundModeEnabled; + if (backgroundSupported) { + isbackgroundModeEnabled = [self boolForKey:@"backgroundmode_preference"]; + } else { + isbackgroundModeEnabled=false; + } + lp_config_set_int(linphone_core_get_config(lc),"app","backgroundmode_preference",backgroundSupported); return YES; } -- (void) enableCodecWithName: (const char*) name andRate: (int) rate to:(id)value{ - LinphoneCore *lc=[LinphoneManager getLc]; - PayloadType *pt; - pt=linphone_core_find_payload_type(lc, name, rate); - if (pt){ - linphone_core_enable_payload_type(lc, pt, [value boolValue]); - } -} - @end diff --git a/Classes/LinphoneUI/LinphoneManager.h b/Classes/LinphoneUI/LinphoneManager.h index b2f4dfc3d..c108d36f8 100644 --- a/Classes/LinphoneUI/LinphoneManager.h +++ b/Classes/LinphoneUI/LinphoneManager.h @@ -66,9 +66,7 @@ typedef struct _LinphoneCallAppData { FastAddressBook* mFastAddressBook; const char* frontCamId; const char* backCamId; - - NSDictionary* currentSettings; - + @public CallContext currentCallContextBeforeGoingBackground; } @@ -92,13 +90,13 @@ typedef struct _LinphoneCallAppData { -(NSString*) getDisplayNameFromAddressBook:(NSString*) number andUpdateCallLog:(LinphoneCallLog*)log; -(UIImage*) getImageFromAddressBook:(NSString*) number; --(BOOL) reconfigureLinphoneIfNeeded:(NSDictionary *)oldSettings; -(void) setupNetworkReachabilityCallback: (const char*) nodeName withContext:(SCNetworkReachabilityContext*) ctx; -(void) refreshRegisters; @property (nonatomic, retain) id callDelegate; @property (nonatomic, retain) id registrationDelegate; @property Connectivity connectivity; +@property (nonatomic) int defaultExpires; @property (readonly) const char* frontCamId; @property (readonly) const char* backCamId; @property (nonatomic) bool isbackgroundModeEnabled; diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index 2188d73c6..92722dae8 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -20,6 +20,7 @@ #import "LinphoneManager.h" #include "linphonecore_utils.h" +#include "lpconfig.h" #include #include #include @@ -42,7 +43,7 @@ extern void libmsx264_init(); #endif #define FRONT_CAM_NAME "AV Capture: Front Camera" #define BACK_CAM_NAME "AV Capture: Back Camera" -#define DEFAULT_EXPIRES 600 + #if defined (HAVE_SILK) extern void libmssilk_init(); #endif @@ -57,12 +58,14 @@ extern void libmsbcg729_init(); @synthesize frontCamId; @synthesize backCamId; @synthesize isbackgroundModeEnabled; +@synthesize defaultExpires; -(id) init { assert (!theLinphoneManager); if ((self= [super init])) { mFastAddressBook = [[FastAddressBook alloc] init]; theLinphoneManager = self; + self.defaultExpires=600; } return self; } @@ -429,14 +432,6 @@ static LinphoneCoreVTable linphonec_vtable = { }; --(void) configurePayloadType:(const char*) type fromPrefKey: (NSString*)key withRate:(int)rate { - if ([[NSUserDefaults standardUserDefaults] boolForKey:key]) { - PayloadType* pt; - if((pt = linphone_core_find_payload_type(theLinphoneCore,type,rate))) { - linphone_core_enable_payload_type(theLinphoneCore,pt, TRUE); - } - } -} -(void) kickOffNetworkConnection { /*start a new thread to avoid blocking the main ui in case of peer host failure*/ [NSThread detachNewThreadSelector:@selector(runNetworkConnection) toTarget:self withObject:nil]; @@ -487,7 +482,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach [[LinphoneManager instance] kickOffNetworkConnection]; } else { Connectivity newConnectivity; - BOOL isWifiOnly = [[NSUserDefaults standardUserDefaults] boolForKey:@"wifi_only_preference"]; + BOOL isWifiOnly = lp_config_get_int(linphone_core_get_config([LinphoneManager getLc]),"app","wifi_only_preference",FALSE); if (!ctx || ctx->testWWan) newConnectivity = flags & kSCNetworkReachabilityFlagsIsWWAN ? wwan:wifi; else @@ -499,7 +494,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach && (lLinphoneMgr.connectivity == newConnectivity || lLinphoneMgr.connectivity == none)) { linphone_proxy_config_expires(proxy, 0); } else if (proxy){ - linphone_proxy_config_expires(proxy, DEFAULT_EXPIRES); //might be better to save the previous value + linphone_proxy_config_expires(proxy, lLinphoneMgr.defaultExpires); //might be better to save the previous value } if (lLinphoneMgr.connectivity == none) { @@ -522,276 +517,29 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach } } --(BOOL) reconfigureLinphoneIfNeeded:(NSDictionary *)settings { - if (theLinphoneCore==nil) { - ms_warning("cannot configure linphone because not initialized yet"); - return NO; - } - - [[NSUserDefaults standardUserDefaults] synchronize]; - NSDictionary* newSettings = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; - if (settings != nil) { - /* reconfigure only if newSettings != settings */ - if ([newSettings isEqualToDictionary:settings]) { - ms_message("Same settings: no need to reconfigure linphone"); - return NO; - } - } - NSLog(@"Configuring Linphone (new settings)"); - - - if ([[NSUserDefaults standardUserDefaults] boolForKey:@"debugenable_preference"]) { - //redirect all traces to the iphone log framework - linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler); - } - else { - linphone_core_disable_logs(); - } - - NSBundle* myBundle = [NSBundle mainBundle]; - - /* unregister before modifying any settings */ - { - LinphoneProxyConfig* proxyCfg; - linphone_core_get_default_proxy(theLinphoneCore, &proxyCfg); - - if (proxyCfg) { - // this will force unregister WITHOUT destorying the proxyCfg object - linphone_proxy_config_edit(proxyCfg); - - int i=0; - while (linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationNone && - linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationCleared && - linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationFailed && - i++<40 ) { - linphone_core_iterate(theLinphoneCore); - usleep(100000); - } - } - } - - const char* lRootCa = [[myBundle pathForResource:@"rootca"ofType:@"pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - linphone_core_set_root_ca(theLinphoneCore, lRootCa); - - NSString* transport = [[NSUserDefaults standardUserDefaults] stringForKey:@"transport_preference"]; - - LCSipTransports transportValue; - if (transport!=nil) { - if (linphone_core_get_sip_transports(theLinphoneCore, &transportValue)) { - ms_error("cannot get current transport"); - } - // Only one port can be set at one time, the others's value is 0 - if ([transport isEqualToString:@"tcp"]) { - if (transportValue.tcp_port == 0) transportValue.tcp_port=transportValue.udp_port + transportValue.tls_port; - transportValue.udp_port=0; - transportValue.tls_port=0; - } else if ([transport isEqualToString:@"udp"]){ - if (transportValue.udp_port == 0) transportValue.udp_port=transportValue.tcp_port + transportValue.tls_port; - transportValue.tcp_port=0; - transportValue.tls_port=0; - } else if ([transport isEqualToString:@"tls"]){ - if (transportValue.tls_port == 0) transportValue.tls_port=transportValue.udp_port + transportValue.tcp_port; - transportValue.tcp_port=0; - transportValue.udp_port=0; - } else { - ms_error("unexpected transport [%s]",[transport cStringUsingEncoding:[NSString defaultCStringEncoding]]); - } - if (linphone_core_set_sip_transports(theLinphoneCore, &transportValue)) { - ms_error("cannot set transport"); - } - } - - - - // Set audio assets - const char* lRing = [[myBundle pathForResource:@"oldphone-mono"ofType:@"wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - linphone_core_set_ring(theLinphoneCore, lRing ); - const char* lRingBack = [[myBundle pathForResource:@"ringback"ofType:@"wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - linphone_core_set_ringback(theLinphoneCore, lRingBack); - - - - //configure sip account - - //madatory parameters - - NSString* username = [[NSUserDefaults standardUserDefaults] stringForKey:@"username_preference"]; - NSString* domain = [[NSUserDefaults standardUserDefaults] stringForKey:@"domain_preference"]; - NSString* accountPassword = [[NSUserDefaults standardUserDefaults] stringForKey:@"password_preference"]; - bool configCheckDisable = [[NSUserDefaults standardUserDefaults] boolForKey:@"check_config_disable_preference"]; - bool isOutboundProxy= [[NSUserDefaults standardUserDefaults] boolForKey:@"outbound_proxy_preference"]; - - - //clear auth info list - linphone_core_clear_all_auth_info(theLinphoneCore); - //clear existing proxy config - linphone_core_clear_proxy_config(theLinphoneCore); - if (username && [username length] >0 && domain && [domain length]>0) { - const char* identity = [[NSString stringWithFormat:@"sip:%@@%@",username,domain] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - const char* password = [accountPassword cStringUsingEncoding:[NSString defaultCStringEncoding]]; - - NSString* proxyAddress = [[NSUserDefaults standardUserDefaults] stringForKey:@"proxy_preference"]; - if ((!proxyAddress || [proxyAddress length] <1 ) && domain) { - proxyAddress = [NSString stringWithFormat:@"sip:%@",domain] ; - } else { - proxyAddress = [NSString stringWithFormat:@"sip:%@",proxyAddress] ; - } - - const char* proxy = [proxyAddress cStringUsingEncoding:[NSString defaultCStringEncoding]]; - - NSString* prefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"prefix_preference"]; - bool substitute_plus_by_00 = [[NSUserDefaults standardUserDefaults] boolForKey:@"substitute_+_by_00_preference"]; - //possible valid config detected - LinphoneProxyConfig* proxyCfg; - proxyCfg = linphone_proxy_config_new(); - - // add username password - LinphoneAddress *from = linphone_address_new(identity); - LinphoneAuthInfo *info; - if (from !=0){ - info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL); - linphone_core_add_auth_info(theLinphoneCore,info); - } - linphone_address_destroy(from); - - // configure proxy entries - linphone_proxy_config_set_identity(proxyCfg,identity); - linphone_proxy_config_set_server_addr(proxyCfg,proxy); - linphone_proxy_config_enable_register(proxyCfg,true); - BOOL isWifiOnly = [[NSUserDefaults standardUserDefaults] boolForKey:@"wifi_only_preference"]; - LinphoneManager* lLinphoneMgr = [LinphoneManager instance]; - if (isWifiOnly && lLinphoneMgr.connectivity == wwan) { - linphone_proxy_config_expires(proxyCfg, 0); - } else { - linphone_proxy_config_expires(proxyCfg, DEFAULT_EXPIRES); - } - - if (isOutboundProxy) - linphone_proxy_config_set_route(proxyCfg,proxy); - - if ([prefix length]>0) { - linphone_proxy_config_set_dial_prefix(proxyCfg, [prefix cStringUsingEncoding:[NSString defaultCStringEncoding]]); - } - linphone_proxy_config_set_dial_escape_plus(proxyCfg,substitute_plus_by_00); - - linphone_core_add_proxy_config(theLinphoneCore,proxyCfg); - //set to default proxy - linphone_core_set_default_proxy(theLinphoneCore,proxyCfg); - - } else { - if (configCheckDisable == false ) { - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Warning",nil) - message:NSLocalizedString(@"It seems you have not configured any proxy server from settings",nil) - delegate:self - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:NSLocalizedString(@"Never remind",nil),nil]; - [error show]; - [error release]; - } - } - - //Configure Codecs - - PayloadType *pt; - //get codecs from linphonerc - const MSList *audioCodecs=linphone_core_get_audio_codecs(theLinphoneCore); - const MSList *elem; - //disable all codecs - for (elem=audioCodecs;elem!=NULL;elem=elem->next){ - pt=(PayloadType*)elem->data; - linphone_core_enable_payload_type(theLinphoneCore,pt,FALSE); - } - - //read codecs from setting bundle and enable them one by one - if ([self isNotIphone3G]) { - [self configurePayloadType:"SILK" fromPrefKey:@"silk_24k_preference" withRate:24000]; - } - else { - ms_message("SILK 24khz codec deactivated"); - } - [self configurePayloadType:"speex" fromPrefKey:@"speex_16k_preference" withRate:16000]; - [self configurePayloadType:"speex" fromPrefKey:@"speex_8k_preference" withRate:8000]; - [self configurePayloadType:"SILK" fromPrefKey:@"silk_16k_preference" withRate:16000]; - [self configurePayloadType:"AMR" fromPrefKey:@"amr_8k_preference" withRate:8000]; - [self configurePayloadType:"GSM" fromPrefKey:@"gsm_8k_preference" withRate:8000]; - [self configurePayloadType:"iLBC" fromPrefKey:@"ilbc_preference" withRate:8000]; - [self configurePayloadType:"PCMU" fromPrefKey:@"pcmu_preference" withRate:8000]; - [self configurePayloadType:"PCMA" fromPrefKey:@"pcma_preference" withRate:8000]; - [self configurePayloadType:"G722" fromPrefKey:@"g722_preference" withRate:8000]; - [self configurePayloadType:"G729" fromPrefKey:@"g729_preference" withRate:8000]; - - //get video codecs from linphonerc - const MSList *videoCodecs=linphone_core_get_video_codecs(theLinphoneCore); - //disable video all codecs - for (elem=videoCodecs;elem!=NULL;elem=elem->next){ - pt=(PayloadType*)elem->data; - linphone_core_enable_payload_type(theLinphoneCore,pt,FALSE); - } - [self configurePayloadType:"MP4V-ES" fromPrefKey:@"mp4v-es_preference" withRate:90000]; - [self configurePayloadType:"H264" fromPrefKey:@"h264_preference" withRate:90000]; - [self configurePayloadType:"VP8" fromPrefKey:@"vp8_preference" withRate:90000]; - - if ([self isNotIphone3G]) { - bool enableVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_video_preference"]; - linphone_core_enable_video(theLinphoneCore, enableVideo, enableVideo); - } else { - linphone_core_enable_video(theLinphoneCore, FALSE, FALSE); - ms_warning("Disable video for phones prior to iPhone 3GS"); - } - bool enableSrtp = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_srtp_preference"]; - linphone_core_set_media_encryption(theLinphoneCore, enableSrtp?LinphoneMediaEncryptionSRTP:LinphoneMediaEncryptionZRTP); - - NSString* stun_server = [[NSUserDefaults standardUserDefaults] stringForKey:@"stun_preference"]; - if ([stun_server length]>0){ - linphone_core_set_stun_server(theLinphoneCore,[stun_server cStringUsingEncoding:[NSString defaultCStringEncoding]]); - linphone_core_set_firewall_policy(theLinphoneCore, LinphonePolicyUseStun); - }else{ - linphone_core_set_stun_server(theLinphoneCore, NULL); - linphone_core_set_firewall_policy(theLinphoneCore, LinphonePolicyNoFirewall); - } - - LinphoneVideoPolicy policy; - policy.automatically_accept = [[NSUserDefaults standardUserDefaults] boolForKey:@"start_video_preference"];; - policy.automatically_initiate = [[NSUserDefaults standardUserDefaults] boolForKey:@"start_video_preference"]; - linphone_core_set_video_policy(theLinphoneCore, &policy); - - UIDevice* device = [UIDevice currentDevice]; - bool backgroundSupported = false; - if ([device respondsToSelector:@selector(isMultitaskingSupported)]) - backgroundSupported = [device isMultitaskingSupported]; - - if (backgroundSupported) { - isbackgroundModeEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"backgroundmode_preference"]; - } else { - isbackgroundModeEnabled=false; - } - - [currentSettings release]; - currentSettings = newSettings; - [currentSettings retain]; - - return YES; -} - (BOOL)isNotIphone3G { - size_t size; - sysctlbyname("hw.machine", NULL, &size, NULL, 0); - char *machine = malloc(size); - sysctlbyname("hw.machine", machine, &size, NULL, 0); - NSString *platform = [[NSString alloc ] initWithUTF8String:machine]; - free(machine); + static BOOL done=FALSE; + static BOOL result; + if (!done){ + size_t size; + sysctlbyname("hw.machine", NULL, &size, NULL, 0); + char *machine = malloc(size); + sysctlbyname("hw.machine", machine, &size, NULL, 0); + NSString *platform = [[NSString alloc ] initWithUTF8String:machine]; + free(machine); - BOOL result = ![platform isEqualToString:@"iPhone1,2"]; + result = ![platform isEqualToString:@"iPhone1,2"]; - [platform release]; + [platform release]; + done=TRUE; + } return result; } // no proxy configured alert - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { - if (buttonIndex == 1) { - [[NSUserDefaults standardUserDefaults] setBool:true forKey:@"check_config_disable_preference"]; - } + } -(void) destroyLibLinphone { [mIterateTimer invalidate]; @@ -906,18 +654,11 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *confiFileName = [[paths objectAtIndex:0] stringByAppendingString:@"/.linphonerc"]; NSString *zrtpSecretsFileName = [[paths objectAtIndex:0] stringByAppendingString:@"/zrtp_secrets"]; + const char* lRootCa = [[myBundle pathForResource:@"rootca"ofType:@"pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; connectivity=none; signal(SIGPIPE, SIG_IGN); //log management - if ([[NSUserDefaults standardUserDefaults] boolForKey:@"debugenable_preference"]) { - //redirect all traces to the iphone log framework - linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler); - } - else { - linphone_core_disable_logs(); - } - libmsilbc_init(); #if defined (HAVE_SILK) libmssilk_init(); @@ -940,13 +681,17 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach , [factoryConfig cStringUsingEncoding:[NSString defaultCStringEncoding]] ,self); - [[NSUserDefaults standardUserDefaults] synchronize];//sync before loading config + linphone_core_set_root_ca(theLinphoneCore, lRootCa); + // Set audio assets + const char* lRing = [[myBundle pathForResource:@"oldphone-mono"ofType:@"wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; + linphone_core_set_ring(theLinphoneCore, lRing ); + const char* lRingBack = [[myBundle pathForResource:@"ringback"ofType:@"wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; + linphone_core_set_ringback(theLinphoneCore, lRingBack); + linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]); [self setupNetworkReachabilityCallback: "linphone.org" withContext:nil]; - - [self reconfigureLinphoneIfNeeded:nil]; // start scheduler mIterateTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 @@ -1001,6 +746,14 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach NSUInteger cpucount = [[NSProcessInfo processInfo] processorCount]; ms_set_cpu_count(cpucount); + if (![self isNotIphone3G]){ + PayloadType *pt=linphone_core_find_payload_type(theLinphoneCore,"SILK",24000); + if (pt) { + linphone_core_enable_payload_type(theLinphoneCore,pt,FALSE); + ms_warning("SILK/24000 and video disabled on old iPhone 3G"); + } + linphone_core_enable_video(theLinphoneCore, FALSE, FALSE); + } ms_warning("Linphone [%s] started on [%s], running with [%u] processor(s)" ,linphone_core_get_version() @@ -1026,15 +779,12 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach //back from standby and background mode is disabled [self startLibLinphone]; } else { - if (![self reconfigureLinphoneIfNeeded:currentSettings]) { - ms_message("becoming active with no config modification, make sure we are registered"); - [self refreshRegisters]; - } + [self refreshRegisters]; } /*IOS specific*/ linphone_core_start_dtmf_stream(theLinphoneCore); - } + -(void) registerLogView:(id) view { mLogView = view; } @@ -1070,7 +820,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach } -(void) settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender { - [self reconfigureLinphoneIfNeeded: currentSettings]; + NSLog(@"settingsViewControllerDidEnd"); } -(NSDictionary*) filterPreferenceSpecifier:(NSDictionary *)specifier { @@ -1086,23 +836,21 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach // child pane maybe NSString* title = [specifier objectForKey:@"Title"]; if ([title isEqualToString:@"Video"]) { - if (!linphone_core_video_enabled(theLinphoneCore)) + if (!linphone_core_video_supported(theLinphoneCore)) return nil; } return specifier; } // NSLog(@"Specifier received: %@", identifier); - if ([identifier isEqualToString:@"srtp_preference"]) { - if (!ortp_srtp_supported()) - return nil; - } else if ([identifier hasPrefix:@"silk"]) { - if ([identifier isEqualToString:@"speex_24k_preference"]) { - if (linphone_core_find_payload_type(theLinphoneCore, "SILK", 24000)) return nil; - } else if ([identifier isEqualToString:@"speex_16k_preference"]) { - if (linphone_core_find_payload_type(theLinphoneCore, "SILK", 16000)) return nil; - } else if ([identifier isEqualToString:@"speex_8k_preference"]) { - if (linphone_core_find_payload_type(theLinphoneCore, "SILK", 8000)) return nil; - } + if ([identifier hasPrefix:@"silk"]) { + if (linphone_core_find_payload_type(theLinphoneCore,"SILK",8000)==NULL){ + return nil; + } + if ([identifier isEqualToString:@"silk_24k_preference"]) { + if (![self isNotIphone3G]) + return nil; + } + } else if ([identifier isEqualToString:@"backgroundmode_preference"]) { UIDevice* device = [UIDevice currentDevice]; if ([device respondsToSelector:@selector(isMultitaskingSupported)]) { diff --git a/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h index 2eaaa2ca0..f98f3b494 100644 --- a/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h +++ b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h @@ -17,6 +17,7 @@ #import #import +#import "IASKSettingsReader.h" #import "IASKSettingsStore.h" #import "IASKViewController.h" @@ -64,6 +65,7 @@ NSMutableArray *_viewList; IASKSettingsReader *_settingsReader; + id _settingsReaderDelegate; id _settingsStore; NSString *_file; @@ -75,6 +77,7 @@ @property (nonatomic, assign) IBOutlet id delegate; @property (nonatomic, copy) NSString *file; +@property (nonatomic, assign) id settingsReaderDelegate; @property (nonatomic, assign) BOOL showCreditsFooter; @property (nonatomic, assign) BOOL showDoneButton; diff --git a/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m index d3593e1b0..557c33730 100644 --- a/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m +++ b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m @@ -63,11 +63,12 @@ CGRect IASKCGRectSwap(CGRect rect); @synthesize showCreditsFooter = _showCreditsFooter; @synthesize showDoneButton = _showDoneButton; @synthesize settingsStore = _settingsStore; +@synthesize settingsReaderDelegate = _settingsReaderDelegate; #pragma mark accessors - (IASKSettingsReader*)settingsReader { if (!_settingsReader) { - _settingsReader = [[IASKSettingsReader alloc] initWithFile:self.file]; + _settingsReader = [[IASKSettingsReader alloc] initWithFile:self.file andDelegate:self.settingsReaderDelegate]; } return _settingsReader; } @@ -267,7 +268,7 @@ CGRect IASKCGRectSwap(CGRect rect); [self.delegate settingsViewControllerDidEnd:self]; } // reload - [self.settingsReader initWithFile:self.file]; + [self.settingsReader initWithFile:self.file andDelegate:self.settingsReaderDelegate]; [self.tableView reloadData]; } @@ -620,9 +621,9 @@ CGRect IASKCGRectSwap(CGRect rect); // load the view controll back in to push it targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex] objectForKey:@"viewController"]; } + targetViewController.settingsReaderDelegate = self.settingsReaderDelegate; targetViewController.file = specifier.file; // changes settingsReader - targetViewController.settingsReader.delegate = self.settingsReader.delegate; - [targetViewController.settingsReader initWithFile:specifier.file]; + targetViewController.title = specifier.title; targetViewController.showCreditsFooter = NO; [[self navigationController] pushViewController:targetViewController animated:YES]; diff --git a/InAppSettingsKit/Models/IASKSettingsReader.h b/InAppSettingsKit/Models/IASKSettingsReader.h index bbdd1a5b5..c66156d8b 100644 --- a/InAppSettingsKit/Models/IASKSettingsReader.h +++ b/InAppSettingsKit/Models/IASKSettingsReader.h @@ -125,10 +125,10 @@ __VA_ARGS__ \ NSDictionary *_settingsBundle; NSArray *_dataSource; NSBundle *_bundle; - id delegate; + id _delegate; } -- (id)initWithFile:(NSString*)file; +- (id)initWithFile:(NSString*)file andDelegate:(id)delegate; - (NSInteger)numberOfSections; - (NSInteger)numberOfRowsForSection:(NSInteger)section; - (IASKSpecifier*)specifierForIndexPath:(NSIndexPath*)indexPath; @@ -145,5 +145,5 @@ __VA_ARGS__ \ @property (nonatomic, retain) NSString *bundlePath; @property (nonatomic, retain) NSDictionary *settingsBundle; @property (nonatomic, retain) NSArray *dataSource; -@property (nonatomic, retain) id delegate; + @end diff --git a/InAppSettingsKit/Models/IASKSettingsReader.m b/InAppSettingsKit/Models/IASKSettingsReader.m index dd82ce72b..7e53458ec 100644 --- a/InAppSettingsKit/Models/IASKSettingsReader.m +++ b/InAppSettingsKit/Models/IASKSettingsReader.m @@ -32,13 +32,13 @@ localizationTable=_localizationTable, bundlePath=_bundlePath, settingsBundle=_settingsBundle, dataSource=_dataSource; -@synthesize delegate; + - (id)init { - return [self initWithFile:@"Root"]; + return [self initWithFile:@"Root" andDelegate:nil]; } -- (id)initWithFile:(NSString*)file { +- (id)initWithFile:(NSString*)file andDelegate:(id)delegate{ if ((self=[super init])) { @@ -61,7 +61,7 @@ dataSource=_dataSource; self.localizationTable = @"Root"; } } - + _delegate=delegate; if (_settingsBundle) { [self _reinterpretBundle:_settingsBundle]; } @@ -86,8 +86,8 @@ dataSource=_dataSource; NSMutableArray *dataSource = [[[NSMutableArray alloc] init] autorelease]; for (NSDictionary *specifier in preferenceSpecifiers) { - if (delegate != nil) { - specifier = [delegate filterPreferenceSpecifier:specifier]; + if (_delegate != nil) { + specifier = [_delegate filterPreferenceSpecifier:specifier]; if (specifier == nil) { // skip continue; @@ -127,7 +127,8 @@ dataSource=_dataSource; - (NSInteger)numberOfRowsForSection:(NSInteger)section { int headingCorrection = [self _sectionHasHeading:section] ? 1 : 0; - return [(NSArray*)[[self dataSource] objectAtIndex:section] count] - headingCorrection; + NSInteger ret= [(NSArray*)[[self dataSource] objectAtIndex:section] count] - headingCorrection; + return ret; } - (IASKSpecifier*)specifierForIndexPath:(NSIndexPath*)indexPath { diff --git a/PhoneMainView.xib b/PhoneMainView.xib index 0052d5e1c..9faf37e10 100644 --- a/PhoneMainView.xib +++ b/PhoneMainView.xib @@ -2,13 +2,13 @@ 784 - 11C74 - 1938 - 1138.23 - 567.00 + 11E53 + 2182 + 1138.47 + 569.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 933 + 1181 YES @@ -67,10 +67,14 @@ IBCocoaTouchFramework NO - - + + + Settings + + NSImage + 20-gear2.png + IBCocoaTouchFramework - 0 @@ -81,7 +85,7 @@ YES IBCocoaTouchFramework NO - + 256 {0, 0} @@ -93,14 +97,12 @@ YES - - Informations - - Information + + + Root View Controller IBCocoaTouchFramework - - MoreViewController + 1 1 @@ -192,14 +194,11 @@ IBCocoaTouchFramework NO - - - Settings - - NSImage - 20-gear2.png - + + + IBCocoaTouchFramework + 0 @@ -210,7 +209,7 @@ YES IBCocoaTouchFramework NO - + 256 {0, 0} @@ -222,12 +221,14 @@ YES - - - Root View Controller + + Informations + + Information IBCocoaTouchFramework - + + MoreViewController 1 1 @@ -237,14 +238,12 @@ - 266 {{0, 431}, {320, 49}} - 3 MCAwAA @@ -541,7 +540,7 @@ 8.IBPluginDependency 9.IBPluginDependency - + YES UIApplication com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -603,6 +602,10 @@ com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 @@ -617,13 +620,13 @@ dialer-orange.png history-orange.png - + YES {26, 28} {25, 24} {25, 23} - 933 + 1181 diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 81e6e686e..97bdf99e3 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -78,7 +78,6 @@ 2242D91710D66BF300E9963F /* out_call.png in Resources */ = {isa = PBXBuildFile; fileRef = 2242D91510D66BF300E9963F /* out_call.png */; }; 2242D9C910D691F900E9963F /* GenericTabViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2242D9C810D691F900E9963F /* GenericTabViewController.m */; }; 2242E313125235120061DDCE /* oldphone-mono-30s.caf in Resources */ = {isa = PBXBuildFile; fileRef = 2242E312125235120061DDCE /* oldphone-mono-30s.caf */; }; - 2245671D107699F700F10948 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2245671C107699F700F10948 /* Settings.bundle */; }; 224567C2107B968500F10948 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 224567C1107B968500F10948 /* AVFoundation.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 2245F78A1201D38000C4179D /* MoreViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 22E0A81B111C44E100B04932 /* MoreViewController.xib */; }; 2248E90E12F7E4CF00220D9C /* UIDigitButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */; }; @@ -312,7 +311,8 @@ 57282931154AF1460076F540 /* history-orange.png in Resources */ = {isa = PBXBuildFile; fileRef = 34C7646B14CD5585008E9607 /* history-orange.png */; }; 57282933154AF14D0076F540 /* dialer-orange.png in Resources */ = {isa = PBXBuildFile; fileRef = 34C7646A14CD5585008E9607 /* dialer-orange.png */; }; 57D2B457157E4580002EA69B /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3415205B1563ABEB00205A0E /* MessageUI.framework */; }; - 57D2B45B1580FF58002EA69B /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 57D2B45A1580FF58002EA69B /* Settings.bundle */; }; + 57D2B47C1586384E002EA69B /* Inappsettings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 57D2B47B15863820002EA69B /* Inappsettings.bundle */; }; + 57D2B47D1586384F002EA69B /* Inappsettings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 57D2B47B15863820002EA69B /* Inappsettings.bundle */; }; 70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 70571E1913FABCB000CDD3C2 /* rootca.pem */; }; 7066FC0C13E830E400EFC6DC /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0B13E830E400EFC6DC /* libvpx.a */; }; 70E542F313E147E3002BA2C0 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F213E147E3002BA2C0 /* OpenGLES.framework */; }; @@ -518,7 +518,6 @@ 2242D9C710D691F900E9963F /* GenericTabViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericTabViewController.h; sourceTree = ""; }; 2242D9C810D691F900E9963F /* GenericTabViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GenericTabViewController.m; sourceTree = ""; }; 2242E312125235120061DDCE /* oldphone-mono-30s.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "oldphone-mono-30s.caf"; path = "liblinphone-sdk/apple-darwin/share/sounds/linphone/rings/oldphone-mono-30s.caf"; sourceTree = ""; }; - 2245671C107699F700F10948 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 224567C1107B968500F10948 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 2248E90C12F7E4CF00220D9C /* UIDigitButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIDigitButton.h; sourceTree = ""; }; 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIDigitButton.m; sourceTree = ""; }; @@ -736,7 +735,7 @@ 34CA8534148F669900503C01 /* VideoViewController-ipad.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "VideoViewController-ipad.xib"; sourceTree = ""; }; 34CA8537148F692A00503C01 /* MainScreenWithVideoPreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainScreenWithVideoPreview.h; sourceTree = ""; }; 34CA8538148F692A00503C01 /* MainScreenWithVideoPreview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainScreenWithVideoPreview.m; sourceTree = ""; }; - 57D2B45A1580FF58002EA69B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; + 57D2B47B15863820002EA69B /* Inappsettings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Inappsettings.bundle; sourceTree = ""; }; 70571E1913FABCB000CDD3C2 /* rootca.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = rootca.pem; path = Resources/rootca.pem; sourceTree = ""; }; 7066FC0B13E830E400EFC6DC /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = "liblinphone-sdk/apple-darwin/lib/libvpx.a"; sourceTree = ""; }; 70E542F213E147E3002BA2C0 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; @@ -1213,7 +1212,7 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( - 57D2B45A1580FF58002EA69B /* Settings.bundle */, + 57D2B47A15863820002EA69B /* settings */, 3415205B1563ABEB00205A0E /* MessageUI.framework */, 34151FB61563A8D800205A0E /* InAppSettingsKit */, 340751961506459A00B89C47 /* CoreTelephony.framework */, @@ -1260,7 +1259,6 @@ 2274402E106F335E006EC466 /* AudioToolbox.framework */, 22744043106F33FC006EC466 /* Security.framework */, 22744056106F9BC9006EC466 /* CoreFoundation.framework */, - 2245671C107699F700F10948 /* Settings.bundle */, 224567C1107B968500F10948 /* AVFoundation.framework */, 22F51EF5107FA66500F98953 /* untitled.plist */, 22B5EFA210CE50BD00777D97 /* AddressBookUI.framework */, @@ -1427,6 +1425,14 @@ path = Xibs; sourceTree = ""; }; + 57D2B47A15863820002EA69B /* settings */ = { + isa = PBXGroup; + children = ( + 57D2B47B15863820002EA69B /* Inappsettings.bundle */, + ); + path = settings; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1504,7 +1510,6 @@ 22F2508F107141E100AC9B3F /* PhoneViewController.xib in Resources */, 22F254811073D99800AC9B3F /* ringback.wav in Resources */, 220FAE4B10767A6A0068D98F /* PhoneMainView.xib in Resources */, - 2245671D107699F700F10948 /* Settings.bundle in Resources */, 22F51EF6107FA66500F98953 /* untitled.plist in Resources */, 2237D4091084D7A9001383EE /* oldphone-mono.wav in Resources */, 227BCDC310D4004600FBFD76 /* CallHistoryTableViewController.xib in Resources */, @@ -1573,6 +1578,7 @@ 34151FF31563A8D800205A0E /* IASKPSToggleSwitchSpecifierViewCell.xib in Resources */, 34151FF41563A8D800205A0E /* IASKSpecifierValuesView.xib in Resources */, 3415205A1563AA8F00205A0E /* 20-gear2.png in Resources */, + 57D2B47C1586384E002EA69B /* Inappsettings.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1580,7 +1586,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 57D2B45B1580FF58002EA69B /* Settings.bundle in Resources */, 22D8F11F147548E2008C97DB /* linphonerc in Resources */, 22D8F120147548E2008C97DB /* PhoneViewController.xib in Resources */, 22D8F121147548E2008C97DB /* ringback.wav in Resources */, @@ -1647,6 +1652,7 @@ 341520081563A93B00205A0E /* IASKPSTextFieldSpecifierViewCell.xib in Resources */, 341520091563A93B00205A0E /* IASKPSToggleSwitchSpecifierViewCell.xib in Resources */, 3415200A1563A93B00205A0E /* IASKSpecifierValuesView.xib in Resources */, + 57D2B47D1586384F002EA69B /* Inappsettings.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/nogpl-thirdparties/Settings.bundle/Advanced.plist b/nogpl-thirdparties/Settings.bundle/Advanced.plist deleted file mode 100644 index c4d0b1f69..000000000 --- a/nogpl-thirdparties/Settings.bundle/Advanced.plist +++ /dev/null @@ -1,103 +0,0 @@ - - - - - PreferenceSpecifiers - - - Key - stun_preference - Title - Stun server - Type - PSTextFieldSpecifier - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - - - DefaultValue - - Key - debugenable_preference - Title - Debug - Type - PSToggleSwitchSpecifier - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - prefix_preference - KeyboardType - NumberPad - Title - Prefix - Type - PSTextFieldSpecifier - - - DefaultValue - - Key - substitute_+_by_00_preference - Title - Substitue + by 00 - Type - PSToggleSwitchSpecifier - - - DefaultValue - udp - Key - transport_preference - Title - Transport - Titles - - udp - tcp - tls - - Type - PSMultiValueSpecifier - Values - - udp - tcp - tls - - - - DefaultValue - - Key - enable_srtp_preference - Title - Secure rtp - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - backgroundmode_preference - Title - Background mode - Type - PSToggleSwitchSpecifier - - - - diff --git a/nogpl-thirdparties/Settings.bundle/Root.plist b/nogpl-thirdparties/Settings.bundle/Root.plist deleted file mode 100644 index 4b6332f8e..000000000 --- a/nogpl-thirdparties/Settings.bundle/Root.plist +++ /dev/null @@ -1,131 +0,0 @@ - - - - - PreferenceSpecifiers - - - Title - SIP account - Type - PSGroupSpecifier - FooterText - Linphone must be restarted for changes to take effect - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - username_preference - KeyboardType - Alphabet - Title - User name - Type - PSTextFieldSpecifier - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - password_preference - KeyboardType - Alphabet - Title - Password - Type - PSTextFieldSpecifier - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - domain_preference - KeyboardType - URL - Title - Domain - Type - PSTextFieldSpecifier - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - proxy_preference - KeyboardType - URL - Title - Proxy - Type - PSTextFieldSpecifier - - - DefaultValue - - Key - outbound_proxy_preference - Title - Outbound proxy - Type - PSToggleSwitchSpecifier - - - Title - - Type - PSGroupSpecifier - - - File - audio - Title - Audio Codecs - Type - PSChildPaneSpecifier - - - File - video - Title - Video - Type - PSChildPaneSpecifier - - - File - Advanced - Title - Advanced - Type - PSChildPaneSpecifier - - - StringsTable - Root - - diff --git a/nogpl-thirdparties/Settings.bundle/audio.plist b/nogpl-thirdparties/Settings.bundle/audio.plist deleted file mode 100644 index 670182e79..000000000 --- a/nogpl-thirdparties/Settings.bundle/audio.plist +++ /dev/null @@ -1,85 +0,0 @@ - - - - - PreferenceSpecifiers - - - Title - Codecs - Type - PSGroupSpecifier - - - DefaultValue - - Key - speex_16k_preference - Title - Speex 16Khz - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - speex_8k_preference - Title - Speex 8Khz - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - g722_preference - Title - G722 - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - gsm_8k_preference - Title - GSM - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - ilbc_preference - Title - ILBC - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - pcmu_preference - Title - PCMU - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - pcma_preference - Title - PCMA - Type - PSToggleSwitchSpecifier - - - - diff --git a/nogpl-thirdparties/Settings.bundle/en.lproj/Root.strings b/nogpl-thirdparties/Settings.bundle/en.lproj/Root.strings deleted file mode 100644 index 8cd87b9d6b20c1fbf87bd4db3db267fca5ad4df9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 546 zcmaixOHRW;5JYRuDMndFh#Ua1V1d}N;sVAV2TO?uC3a9aJn*VxFrY}tnon0(S66#J z-d9>G>6W!ur(SDqlp`9nn~*(m%iWnv?yq`Qfp6XbK1?+om~~#r)ZnhkYQU_VbfjuT zHNn`CX<0sd*m1A}>&5sU$akD=GTXJ1e diff --git a/nogpl-thirdparties/Settings.bundle/video.plist b/nogpl-thirdparties/Settings.bundle/video.plist deleted file mode 100644 index 976ec6284..000000000 --- a/nogpl-thirdparties/Settings.bundle/video.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - PreferenceSpecifiers - - - Type - PSToggleSwitchSpecifier - Title - Enable video - Key - enable_video_preference - DefaultValue - - - - Type - PSToggleSwitchSpecifier - Title - Automatically start video - Key - start_video_preference - DefaultValue - - - - Title - Codecs - Type - PSGroupSpecifier - - - DefaultValue - - Key - vp8_preference - Title - VP8 - Type - PSToggleSwitchSpecifier - - - - diff --git a/Settings.bundle/Advanced.plist b/settings/Inappsettings.bundle/Advanced.plist similarity index 100% rename from Settings.bundle/Advanced.plist rename to settings/Inappsettings.bundle/Advanced.plist diff --git a/Settings.bundle/Root.plist b/settings/Inappsettings.bundle/Root.plist similarity index 100% rename from Settings.bundle/Root.plist rename to settings/Inappsettings.bundle/Root.plist diff --git a/Settings.bundle/audio.plist b/settings/Inappsettings.bundle/audio.plist similarity index 100% rename from Settings.bundle/audio.plist rename to settings/Inappsettings.bundle/audio.plist diff --git a/Settings.bundle/en.lproj/Root.strings b/settings/Inappsettings.bundle/en.lproj/Root.strings similarity index 100% rename from Settings.bundle/en.lproj/Root.strings rename to settings/Inappsettings.bundle/en.lproj/Root.strings diff --git a/Settings.bundle/video.plist b/settings/Inappsettings.bundle/video.plist similarity index 100% rename from Settings.bundle/video.plist rename to settings/Inappsettings.bundle/video.plist diff --git a/submodules/libilbc-rfc3951 b/submodules/libilbc-rfc3951 index af32518af..a70714c2e 160000 --- a/submodules/libilbc-rfc3951 +++ b/submodules/libilbc-rfc3951 @@ -1 +1 @@ -Subproject commit af32518af41f97caee07070234a3475409b9a27d +Subproject commit a70714c2e8a1f6f9958450cb612e3dc9895981e7 From 4a0e4e1ee89b63f84f89758682ceb83b96326d30 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 12 Jun 2012 17:48:43 +0200 Subject: [PATCH 7/8] inapp settings mostly finished. --- Classes/FirstLoginViewController.m | 15 ++- Classes/IncallViewController.m | 2 +- Classes/LinphoneAppDelegate.m | 53 ++--------- Classes/LinphoneCoreSettingsStore.h | 1 + Classes/LinphoneCoreSettingsStore.m | 136 +++++++++++++++++---------- Classes/LinphoneUI/LinphoneManager.h | 7 +- Classes/LinphoneUI/LinphoneManager.m | 72 ++++++++++---- Classes/MainScreenWithVideoPreview.m | 12 +-- Classes/MoreViewController.m | 3 +- Classes/PhoneViewController.m | 15 +-- linphonerc | 6 +- linphonerc-ipad | 4 - submodules/linphone | 2 +- 13 files changed, 175 insertions(+), 153 deletions(-) diff --git a/Classes/FirstLoginViewController.m b/Classes/FirstLoginViewController.m index 69ae3149d..647b50c58 100644 --- a/Classes/FirstLoginViewController.m +++ b/Classes/FirstLoginViewController.m @@ -33,12 +33,10 @@ - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - //[username setText:[[NSUserDefaults standardUserDefaults] stringForKey:@"username_preference"]]; - //[passwd setText:[[NSUserDefaults standardUserDefaults] stringForKey:@"password_preference"]]; } -(void) viewDidLoad { - NSString* siteUrl = [[NSUserDefaults standardUserDefaults] stringForKey:@"firt_login_view_url"]; + NSString* siteUrl = [[NSUserDefaults standardUserDefaults] stringForKey:@"first_login_view_url"]; if (siteUrl==nil) { siteUrl=@"http://www.linphone.org"; } @@ -79,9 +77,8 @@ [error show]; [error release]; } else { - [[NSUserDefaults standardUserDefaults] setObject:username.text forKey:@"username_preference"]; - [[NSUserDefaults standardUserDefaults] setObject:passwd.text forKey:@"password_preference"]; - [[LinphoneManager instance] reconfigureLinphoneIfNeeded:nil]; + [[LinphoneManager instance].settingsStore setObject:username.text forKey:@"username_preference"]; + [[LinphoneManager instance].settingsStore setObject:passwd.text forKey:@"password_preference"]; [self.activityIndicator setHidden:false]; }; @@ -106,9 +103,9 @@ // otherButtonTitles:nil ,nil]; //[error show]; //[error release]; - //erase uername passwd - [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"username_preference"]; - [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"password_preference"]; + //erase username passwd + [[LinphoneManager instance].settingsStore setObject:Nil forKey:@"username_preference"]; + [[LinphoneManager instance].settingsStore setObject:Nil forKey:@"password_preference"]; } -(void) displayNotRegisteredFromUI:(UIViewController*) viewCtrl { [self.activityIndicator setHidden:true]; diff --git a/Classes/IncallViewController.m b/Classes/IncallViewController.m index 31a06e8aa..895299e67 100644 --- a/Classes/IncallViewController.m +++ b/Classes/IncallViewController.m @@ -617,7 +617,7 @@ void addAnimationFadeTransition(UIView* view, float duration) { UIDevice* device = [UIDevice currentDevice]; if ([device respondsToSelector:@selector(isMultitaskingSupported)] && [device isMultitaskingSupported]) { - bool enableVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_video_preference"]; + bool enableVideo = linphone_core_video_enabled([LinphoneManager getLc]); [LinphoneManager set:contacts hidden:enableVideo withName:"CONTACT button" andReason:AT]; [LinphoneManager set:addVideo hidden:!contacts.hidden withName:"ADD_VIDEO button" andReason:AT]; diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index f11c2a97b..80cc25779 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -86,6 +86,8 @@ int __aeabi_idiv(int a, int b) { } - (void)applicationDidEnterBackground:(UIApplication *)application { + if (settingsController.settingsStore!=Nil) + [settingsController.settingsStore synchronize]; if (![[LinphoneManager instance] enterBackgroundMode]) { // destroying eventHandler if app cannot go in background. // Otherwise if a GSM call happen and Linphone is resumed, @@ -138,34 +140,8 @@ int __aeabi_idiv(int a, int b) { } - (void) loadDefaultSettings:(NSDictionary *) appDefaults { - - NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"]; - if(!settingsBundle) { - NSLog(@"Could not find Settings.bundle"); - return; - } - - NSMutableDictionary *rootSettings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]]; - NSMutableDictionary *audioSettings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"audio.plist"]]; - NSMutableDictionary *videoSettings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"video.plist"]]; - NSMutableDictionary *advancedSettings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Advanced.plist"]]; - - NSMutableArray *preferences = [rootSettings objectForKey:@"PreferenceSpecifiers"]; - [preferences addObjectsFromArray:[audioSettings objectForKey:@"PreferenceSpecifiers"]]; - [preferences addObjectsFromArray:[videoSettings objectForKey:@"PreferenceSpecifiers"]]; - [preferences addObjectsFromArray:[advancedSettings objectForKey:@"PreferenceSpecifiers"]]; - - NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]]; - - for(NSDictionary *prefSpecification in preferences) { - NSString *key = [prefSpecification objectForKey:@"Key"]; - if(key && [prefSpecification objectForKey:@"DefaultValue"]) { - [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key]; - } - } - [defaultsToRegister addEntriesFromDictionary:appDefaults]; - [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister]; - [defaultsToRegister release]; + [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; + [appDefaults release]; [[NSUserDefaults standardUserDefaults] synchronize]; } @@ -204,22 +180,14 @@ int __aeabi_idiv(int a, int b) { } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ - NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: - @"NO", @"enable_first_login_view_preference", // -#ifdef HAVE_AMR - @"YES",@"amr_8k_preference", // enable amr by default if compiled with -#endif -#ifdef HAVE_G729 - @"YES",@"g729_preference", // enable amr by default if compiled with -#endif - //@"+33",@"countrycode_preference", - nil]; - + NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: nil]; + // Put your default NSUserDefaults settings in the dictionary above. + [self loadDefaultSettings: appDefaults]; if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)] && [UIApplication sharedApplication].applicationState == UIApplicationStateBackground - && [[NSUserDefaults standardUserDefaults] boolForKey:@"disable_autoboot_preference"]) { + && ![[NSUserDefaults standardUserDefaults] boolForKey:@"start_at_boot_preference"]) { // autoboot disabled, doing nothing } else { [self startApplication]; @@ -240,11 +208,8 @@ int __aeabi_idiv(int a, int b) { // Settings, setup delegate settingsController.delegate = [LinphoneManager instance]; settingsController.settingsReaderDelegate = [LinphoneManager instance]; - settingsController.settingsStore=[[LinphoneCoreSettingsStore alloc] init]; - //settingsController.file=@"settings/Inappsettings.bundle"; + [LinphoneManager instance].settingsStore=settingsController.settingsStore=[[LinphoneCoreSettingsStore alloc] init]; settingsController.showCreditsFooter=FALSE; - //[settingsController.settingsReader init]; - [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound]; diff --git a/Classes/LinphoneCoreSettingsStore.h b/Classes/LinphoneCoreSettingsStore.h index af1f272c2..2014e49aa 100644 --- a/Classes/LinphoneCoreSettingsStore.h +++ b/Classes/LinphoneCoreSettingsStore.h @@ -13,6 +13,7 @@ @interface LinphoneCoreSettingsStore : IASKAbstractSettingsStore { NSDictionary *dict; + NSDictionary *changedDict; } -(void) transformLinphoneCoreToKeys; diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index 0df80d755..fff6669ed 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -11,44 +11,33 @@ #include "lpconfig.h" -struct codec_name_pref_table{ - const char *name; - int rate; - NSString *prefname; -}; +extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); -struct codec_name_pref_table codec_pref_table[]={ - { "speex", 8000, @"speex_8k_preference" }, - { "speex", 16000, @"speex_16k_preference" }, - { "silk", 24000, @"silk_24k_preference" }, - { "silk", 16000, @"silk_16k_preference" }, - { "amr", 8000, @"amr_8k_preference" }, - { "ilbc", 8000, @"ilbc_preference"}, - { "pcmu", 8000, @"pcmu_preference"}, - { "pcma", 8000, @"pcma_preference"}, - { "g722", 8000, @"g722_preference"}, - { "g729", 8000, @"g729_preference"}, - { "mp4v-es", 90000, @"mp4v-es_preference"}, - { "h264", 90000, @"h264_preference"}, - { "vp8", 90000, @"vp8_preference"}, - { NULL,0,Nil } -}; - -static NSString *getPrefForCodec(const char *name, int rate){ - int i; - for(i=0;codec_pref_table[i].name!=NULL;++i){ - if (strcasecmp(codec_pref_table[i].name,name)==0 && codec_pref_table[i].rate==rate) - return codec_pref_table[i].prefname; - } - return Nil; -} @implementation LinphoneCoreSettingsStore +-(void) handleMigration{ + + NSUserDefaults *oldconfig=[NSUserDefaults standardUserDefaults]; + NSArray *allkeys=[[oldconfig dictionaryRepresentation] allKeys]; + for(NSString* key in allkeys){ + NSLog(@"Migrating old config item %@ to in app settings.",key); + [self setObject:[oldconfig objectForKey:key] forKey:key]; + } + [self synchronize]; + NSLog(@"Migration done"); +} + -(id) init{ self = [super init]; if (self){ dict=[[NSMutableDictionary alloc] init]; + changedDict=[[NSMutableDictionary alloc] init]; + LinphoneCore *lc=[LinphoneManager getLc]; + if (lp_config_get_int(linphone_core_get_config(lc),"app","config_migrated",0)==0){ + [self handleMigration]; + lp_config_set_int(linphone_core_get_config(lc),"app","config_migrated",1); + } [self transformLinphoneCoreToKeys]; } return self; @@ -57,6 +46,7 @@ static NSString *getPrefForCodec(const char *name, int rate){ -(void) dealloc{ [super dealloc]; [dict release]; + [changedDict release]; } -(void) transformKeysToLinphoneCore{ @@ -79,7 +69,7 @@ static NSString *getPrefForCodec(const char *name, int rate){ const MSList *elem=codecs; for(;elem!=NULL;elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; - NSString *pref=getPrefForCodec(pt->mime_type,pt->clock_rate); + NSString *pref=[LinphoneManager getPrefForCodec:pt->mime_type withRate:pt->clock_rate]; if (pref){ [self setBool: linphone_core_payload_type_enabled(lc,pt) forKey: pref]; }else{ @@ -163,7 +153,14 @@ static NSString *getPrefForCodec(const char *name, int rate){ [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","check_config_disable_preference",0) forKey:@"check_config_disable_preference"]; [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","wifi_only_preference",0) forKey:@"wifi_only_preference"]; [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","backgroundmode_preference",TRUE) forKey:@"backgroundmode_preference"]; - [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","start_at_boot_preference",TRUE) forKey:@"disable_autoboot_preference"]; + /*keep this one also in the standardUserDefaults so that it can be read before starting liblinphone*/ + BOOL start_at_boot; + if ([[NSUserDefaults standardUserDefaults] objectForKey:@"start_at_boot_preference"]==Nil) + start_at_boot=TRUE; + else start_at_boot=[[NSUserDefaults standardUserDefaults] boolForKey:@"start_at_boot_preference"]; + [self setBool: start_at_boot forKey:@"start_at_boot_preference"]; + + if (linphone_core_tunnel_available()){ /*FIXME: enhance linphonecore API to handle tunnel more easily in applications */ @@ -178,30 +175,32 @@ static NSString *getPrefForCodec(const char *name, int rate){ pol=linphone_core_get_video_policy(lc); [self setBool:(pol->automatically_accept && pol->automatically_initiate) forKey:@"start_video_preference"]; } + if (lp_config_get_int(linphone_core_get_config(lc),"app","debugenable_preference",0)) + linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler); + + [changedDict release]; + changedDict=[[NSMutableDictionary alloc] init]; } -(void) setObject:(id)value forKey:(NSString *)key { [dict setValue:value forKey:key]; - NSString *changed_value=[[NSString alloc] initWithFormat:@"%@_changed", key]; - [dict setValue:[NSNumber numberWithBool:TRUE] forKey:changed_value]; - [changed_value release]; + [changedDict setValue:[NSNumber numberWithBool:TRUE] forKey:key]; } - (id)objectForKey:(NSString*)key { return [dict valueForKey:key]; } -- (BOOL)synchronize { +- (BOOL)valueChangedForKey:(NSString*)key{ + return [ [changedDict valueForKey:key] boolValue]; +} + +- (void) synchronizeAccount{ LinphoneCore *lc=[LinphoneManager getLc]; LinphoneManager* lLinphoneMgr = [LinphoneManager instance]; - - NSLog(@"Called in SettingsStore synchronize"); - if ([self boolForKey:@"username_preference_changed"]) - NSLog(@"username_preference_changed !!"); - return YES; + LinphoneProxyConfig* proxyCfg=NULL; /* unregister before modifying any settings */ { - LinphoneProxyConfig* proxyCfg; linphone_core_get_default_proxy(lc, &proxyCfg); if (proxyCfg) { @@ -221,7 +220,7 @@ static NSString *getPrefForCodec(const char *name, int rate){ NSString* transport = [self stringForKey:@"transport_preference"]; - LCSipTransports transportValue; + LCSipTransports transportValue={0}; if (transport!=nil) { if (linphone_core_get_sip_transports(lc, &transportValue)) { ms_error("cannot get current transport"); @@ -266,7 +265,7 @@ static NSString *getPrefForCodec(const char *name, int rate){ const char* identity = [[NSString stringWithFormat:@"sip:%@@%@",username,domain] cStringUsingEncoding:[NSString defaultCStringEncoding]]; const char* password = [accountPassword cStringUsingEncoding:[NSString defaultCStringEncoding]]; - NSString* proxyAddress = [[NSUserDefaults standardUserDefaults] stringForKey:@"proxy_preference"]; + NSString* proxyAddress = [self stringForKey:@"proxy_preference"]; if ((!proxyAddress || [proxyAddress length] <1 ) && domain) { proxyAddress = [NSString stringWithFormat:@"sip:%@",domain] ; } else { @@ -275,10 +274,10 @@ static NSString *getPrefForCodec(const char *name, int rate){ const char* proxy = [proxyAddress cStringUsingEncoding:[NSString defaultCStringEncoding]]; - NSString* prefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"prefix_preference"]; - bool substitute_plus_by_00 = [[NSUserDefaults standardUserDefaults] boolForKey:@"substitute_+_by_00_preference"]; + NSString* prefix = [self stringForKey:@"prefix_preference"]; + bool substitute_plus_by_00 = [self boolForKey:@"substitute_+_by_00_preference"]; //possible valid config detected - LinphoneProxyConfig* proxyCfg; + proxyCfg = linphone_proxy_config_new(); // add username password @@ -314,20 +313,41 @@ static NSString *getPrefForCodec(const char *name, int rate){ //set to default proxy linphone_core_set_default_proxy(lc,proxyCfg); - } + } +} + +- (BOOL)synchronize { + LinphoneCore *lc=[LinphoneManager getLc]; + if (lc==NULL) return YES; + BOOL account_changed; + + account_changed=[self valueChangedForKey:@"username_preference"] + || [self valueChangedForKey:@"password_preference"] + || [self valueChangedForKey:@"domain_preference"] + || [self valueChangedForKey:@"proxy_preference"] + || [self valueChangedForKey:@"outbound_proxy_preference"] + || [self valueChangedForKey:@"transport_preference"] + || [self valueChangedForKey:@"prefix_preference"] + || [self valueChangedForKey:@"substitute_+_by_00_preference"]; + + if (account_changed) + [self synchronizeAccount]; + //Configure Codecs PayloadType *pt; const MSList *elem; - //disable all codecs + for (elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){ pt=(PayloadType*)elem->data; - linphone_core_enable_payload_type(lc,pt,[self boolForKey: getPrefForCodec(pt->mime_type,pt->clock_rate)]); + NSString *pref=[LinphoneManager getPrefForCodec:pt->mime_type withRate:pt->clock_rate]; + linphone_core_enable_payload_type(lc,pt,[self boolForKey: pref]); } for (elem=linphone_core_get_video_codecs(lc);elem!=NULL;elem=elem->next){ pt=(PayloadType*)elem->data; - linphone_core_enable_payload_type(lc,pt,[self boolForKey: getPrefForCodec(pt->mime_type,pt->clock_rate)]); + NSString *pref=[LinphoneManager getPrefForCodec:pt->mime_type withRate:pt->clock_rate]; + linphone_core_enable_payload_type(lc,pt,[self boolForKey: pref]); } bool enableVideo = [self boolForKey:@"enable_video_preference"]; @@ -364,7 +384,19 @@ static NSString *getPrefForCodec(const char *name, int rate){ } else { isbackgroundModeEnabled=false; } - lp_config_set_int(linphone_core_get_config(lc),"app","backgroundmode_preference",backgroundSupported); + lp_config_set_int(linphone_core_get_config(lc),"app","backgroundmode_preference",isbackgroundModeEnabled); + + BOOL debugmode=[self boolForKey:@"debugenable_preference"]; + lp_config_set_int(linphone_core_get_config(lc),"app","debugenable_preference",debugmode); + if (debugmode) linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler); + else linphone_core_disable_logs(); + + /*keep this one also in the standardUserDefaults so that it can be read before starting liblinphone*/ + BOOL start_at_boot=[self boolForKey:@"start_at_boot_preference"]; + [[NSUserDefaults standardUserDefaults] setBool: start_at_boot forKey:@"start_at_boot_preference"]; + + [changedDict release]; + changedDict=[[NSMutableDictionary alloc] init]; return YES; } diff --git a/Classes/LinphoneUI/LinphoneManager.h b/Classes/LinphoneUI/LinphoneManager.h index c108d36f8..754bf9808 100644 --- a/Classes/LinphoneUI/LinphoneManager.h +++ b/Classes/LinphoneUI/LinphoneManager.h @@ -24,6 +24,7 @@ #import "LogView.h" #import "LinphoneUIDelegates.h" #import "IASKSettingsReader.h" +#import "IASKSettingsStore.h" #import "IASKAppSettingsViewController.h" typedef enum _Connectivity { @@ -66,7 +67,7 @@ typedef struct _LinphoneCallAppData { FastAddressBook* mFastAddressBook; const char* frontCamId; const char* backCamId; - + id settingsStore; @public CallContext currentCallContextBeforeGoingBackground; } @@ -75,6 +76,7 @@ typedef struct _LinphoneCallAppData { +(BOOL) runningOnIpad; +(void) set:(UIView*)view hidden: (BOOL) hidden withName:(const char*)name andReason:(const char*) reason; +(void) logUIElementPressed:(const char*) name; ++ (NSString *) getPrefForCodec: (const char*) name withRate: (int) rate; -(void) displayDialer; @@ -95,10 +97,11 @@ typedef struct _LinphoneCallAppData { @property (nonatomic, retain) id callDelegate; @property (nonatomic, retain) id registrationDelegate; +@property (nonatomic, retain) id settingsStore; @property Connectivity connectivity; @property (nonatomic) int defaultExpires; @property (readonly) const char* frontCamId; @property (readonly) const char* backCamId; -@property (nonatomic) bool isbackgroundModeEnabled; + @end diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index 92722dae8..35f77c04c 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -57,8 +57,41 @@ extern void libmsbcg729_init(); @synthesize connectivity; @synthesize frontCamId; @synthesize backCamId; -@synthesize isbackgroundModeEnabled; @synthesize defaultExpires; +@synthesize settingsStore; + +struct codec_name_pref_table{ +const char *name; +int rate; +NSString *prefname; +}; + +struct codec_name_pref_table codec_pref_table[]={ + { "speex", 8000, @"speex_8k_preference" }, + { "speex", 16000, @"speex_16k_preference" }, + { "silk", 24000, @"silk_24k_preference" }, + { "silk", 16000, @"silk_16k_preference" }, + { "amr", 8000, @"amr_8k_preference" }, + { "ilbc", 8000, @"ilbc_preference"}, + { "pcmu", 8000, @"pcmu_preference"}, + { "pcma", 8000, @"pcma_preference"}, + { "g722", 8000, @"g722_preference"}, + { "g729", 8000, @"g729_preference"}, + { "mp4v-es", 90000, @"mp4v-es_preference"}, + { "h264", 90000, @"h264_preference"}, + { "vp8", 90000, @"vp8_preference"}, + { NULL,0,Nil } +}; + ++ (NSString *) getPrefForCodec: (const char*) name withRate: (int) rate{ + int i; + for(i=0;codec_pref_table[i].name!=NULL;++i){ + if (strcasecmp(codec_pref_table[i].name,name)==0 && codec_pref_table[i].rate==rate) + return codec_pref_table[i].prefname; + } + return Nil; +} + -(id) init { assert (!theLinphoneManager); @@ -289,9 +322,12 @@ extern void libmsbcg729_init(); } +(LinphoneCore*) getLc { +#if 0 if (theLinphoneCore==nil) { @throw([NSException exceptionWithName:@"LinphoneCoreException" reason:@"Linphone core not initialized yet" userInfo:nil]); } +#else +#endif return theLinphoneCore; } @@ -302,7 +338,7 @@ extern void libmsbcg729_init(); [callDelegate displayStatus:message]; } //generic log handler for debug version -static void linphone_iphone_log_handler(int lev, const char *fmt, va_list args){ +void linphone_iphone_log_handler(int lev, const char *fmt, va_list args){ NSString* format = [[NSString alloc] initWithCString:fmt encoding:[NSString defaultCStringEncoding]]; NSLogv(format,args); NSString* formatedString = [[NSString alloc] initWithFormat:format arguments:args]; @@ -564,7 +600,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach linphone_core_get_default_proxy(theLinphoneCore, &proxyCfg); linphone_core_stop_dtmf_stream(theLinphoneCore); - if (isbackgroundModeEnabled && proxyCfg) { + if (proxyCfg && lp_config_get_int(linphone_core_get_config(theLinphoneCore),"app","backgroundmode_preference",0)) { //For registration register linphone_core_refresh_registers(theLinphoneCore); @@ -595,10 +631,6 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach } else { ms_warning("keepalive handler cannot be registered"); } - LCSipTransports transportValue; - if (linphone_core_get_sip_transports(theLinphoneCore, &transportValue)) { - ms_error("cannot get current transport"); - } return YES; } else { @@ -820,7 +852,16 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach } -(void) settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender { - NSLog(@"settingsViewControllerDidEnd"); +} + +-(BOOL) codecSupported:(NSString *) prefName{ + int i; + for(i=0;codec_pref_table[i].name!=NULL;++i){ + if ([prefName compare:codec_pref_table[i].prefname]==0){ + return linphone_core_find_payload_type(theLinphoneCore,codec_pref_table[i].name, codec_pref_table[i].rate)!=NULL; + } + } + return TRUE; } -(NSDictionary*) filterPreferenceSpecifier:(NSDictionary *)specifier { @@ -842,16 +883,11 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach return specifier; } // NSLog(@"Specifier received: %@", identifier); - if ([identifier hasPrefix:@"silk"]) { - if (linphone_core_find_payload_type(theLinphoneCore,"SILK",8000)==NULL){ + if ([identifier isEqualToString:@"silk_24k_preference"]) { + if (![self isNotIphone3G]) return nil; - } - if ([identifier isEqualToString:@"silk_24k_preference"]) { - if (![self isNotIphone3G]) - return nil; - } - - } else if ([identifier isEqualToString:@"backgroundmode_preference"]) { + } + if ([identifier isEqualToString:@"backgroundmode_preference"]) { UIDevice* device = [UIDevice currentDevice]; if ([device respondsToSelector:@selector(isMultitaskingSupported)]) { if ([device isMultitaskingSupported]) { @@ -861,6 +897,8 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach // hide setting if bg mode not supported return nil; } + if (![self codecSupported:identifier]) + return Nil; return specifier; } diff --git a/Classes/MainScreenWithVideoPreview.m b/Classes/MainScreenWithVideoPreview.m index c35983820..802bbccca 100644 --- a/Classes/MainScreenWithVideoPreview.m +++ b/Classes/MainScreenWithVideoPreview.m @@ -129,14 +129,12 @@ -(void) showPreview:(BOOL) show { LinphoneCore* lc; - @try { - lc = [LinphoneManager getLc]; - } - @catch (NSException *exception) { - return; - } - bool enableVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_video_preference"]; + lc = [LinphoneManager getLc]; + + if (lc==NULL) return; + + bool enableVideo = linphone_core_video_enabled(lc); if (enableVideo) { LinphoneCall* call = linphone_core_get_current_call(lc); diff --git a/Classes/MoreViewController.m b/Classes/MoreViewController.m index b2b9e4a96..db04b56ff 100644 --- a/Classes/MoreViewController.m +++ b/Classes/MoreViewController.m @@ -20,6 +20,7 @@ #import "MoreViewController.h" #include "ConsoleViewController.h" #import "LinphoneManager.h" +#include "lpconfig.h" @implementation MoreViewController @@ -36,7 +37,7 @@ [creditText setText: [NSString stringWithFormat:creditText.text,[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]]; consoleViewController = [[ConsoleViewController alloc] initWithNibName:@"ConsoleViewController" bundle:[NSBundle mainBundle]]; [[LinphoneManager instance] registerLogView:consoleViewController]; - isDebug = [[NSUserDefaults standardUserDefaults] boolForKey:@"debugenable_preference"]; + isDebug = lp_config_get_int(linphone_core_get_config([LinphoneManager getLc]),"app","debugenable_preference",0); } diff --git a/Classes/PhoneViewController.m b/Classes/PhoneViewController.m index 7309144ad..34e842e5f 100644 --- a/Classes/PhoneViewController.m +++ b/Classes/PhoneViewController.m @@ -101,8 +101,9 @@ } -(void) updateCallAndBackButtons { - @try { - bool zeroCall = (linphone_core_get_calls_nb([LinphoneManager getLc]) == 0); + LinphoneCore *lc=[LinphoneManager getLc]; + if (lc){ + bool zeroCall = (linphone_core_get_calls_nb(lc) == 0); [LinphoneManager set:callLarge hidden:!zeroCall withName:"CALL_LARGE button" andReason:__FUNCTION__]; [LinphoneManager set:switchCamera hidden:!zeroCall withName:"SWITCH_CAM button" andReason:__FUNCTION__]; @@ -112,14 +113,8 @@ [callShort setTitle:[UICallButton transforModeEnabled] ? @"transfer":@"call" forState:UIControlStateNormal]; if (!callShort.hidden) - [callShort setEnabled:!linphone_core_sound_resources_locked([LinphoneManager getLc])]; - } @catch (NSException* exc) { - // R.A.S: linphone core si simply not ready... - ms_warning("Catched exception %s: %s", - [exc.name cStringUsingEncoding:[NSString defaultCStringEncoding]], - [exc.reason cStringUsingEncoding:[NSString defaultCStringEncoding]]); - } - + [callShort setEnabled:!linphone_core_sound_resources_locked(lc)]; + } [self updateStatusSubView]; } diff --git a/linphonerc b/linphonerc index 6dd0d69b0..9a2ba91f6 100644 --- a/linphonerc +++ b/linphonerc @@ -6,21 +6,17 @@ mtu=1300 [sip] sip_random_port=1 -sip_port=5060 sip_tcp_random_port=1 -sip_tcp_port=0 sip_tls_random_port=1 -sip_tls_port=0 guess_hostname=1 contact=sip:toto@unknown-host inc_timeout=15 use_info=0 use_ipv6=0 -default_proxy=-1 register_only_when_network_is_up=1 auto_net_state_mon=0 keepalive_period=30000 -media_encryption=zrtp + [rtp] audio_rtp_port=7076 diff --git a/linphonerc-ipad b/linphonerc-ipad index f537c1ee1..075adf31c 100644 --- a/linphonerc-ipad +++ b/linphonerc-ipad @@ -6,17 +6,13 @@ mtu=1300 [sip] sip_random_port=1 -sip_port=5060 sip_tcp_random_port=1 -sip_tcp_port=0 sip_tls_random_port=1 -sip_tls_port=0 guess_hostname=1 contact=sip:toto@unknown-host inc_timeout=15 use_info=0 use_ipv6=0 -default_proxy=-1 register_only_when_network_is_up=1 auto_net_state_mon=0 keepalive_period=30000 diff --git a/submodules/linphone b/submodules/linphone index bad6c152f..23d589cec 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit bad6c152f1521de8648d47c70e9321b7668b40b5 +Subproject commit 23d589cec01361b7c08528cd7433d5b01c0579bb From 8ee76a7675c5921a8f8b478330618769bccbbdc8 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 18 Jun 2012 15:13:19 +0200 Subject: [PATCH 8/8] update linphone submodule --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index 2d669353c..630e26944 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 2d669353c3eda22e63023fde2f3cde7b437d2c81 +Subproject commit 630e26944dd6e5cca53787452b162ec6baf7ba48