Merge branch 'master' into tunnel

Conflicts:
	Classes/LinphoneUI/LinphoneManager.h
	Classes/LinphoneUI/LinphoneManager.m
	Settings.bundle/Root.plist
	Settings/InAppSettings.bundle/Root.plist
	linphone.xcodeproj/project.pbxproj
	submodules/build/builders.d/x264.mk
This commit is contained in:
Yann Diorcet 2013-01-15 12:58:42 +01:00
commit 233f22e5d7
967 changed files with 179775 additions and 17688 deletions

3
.gitignore vendored
View file

@ -1 +1,4 @@
build-*
*.locuser
.DS_Store
liblinphone-sdk

View file

@ -1,4 +1,4 @@
/* MoreViewController.h
/* AboutViewController.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
@ -18,31 +18,22 @@
*/
#import <UIKit/UIKit.h>
#include "linphoneAppDelegate.h"
#import "UICompositeViewController.h"
@class ConsoleViewController;
@interface MoreViewController : UITableViewController {
bool isLogViewEnabled;
UITableViewCell *credit;
UITextView *creditText;
UITableViewCell *web;
UILabel *weburi;
UITableViewCell *console;
ConsoleViewController *consoleViewController;
bool isDebug;
@interface AboutViewController : UIViewController<UICompositeViewDelegate, UIWebViewDelegate> {
}
@property (nonatomic, retain) IBOutlet UITableViewCell* web;
@property (nonatomic, retain) IBOutlet UITableViewCell* credit;
@property (nonatomic, retain) IBOutlet UITableViewCell* console;
@property (nonatomic, retain) IBOutlet UITextView *creditText;
@property (nonatomic, retain) IBOutlet UILabel *weburi;
@property (nonatomic, retain) IBOutlet UILabel *linphoneLabel;
@property (nonatomic, retain) IBOutlet UILabel *linphoneIphoneVersionLabel;
@property (nonatomic, retain) IBOutlet UILabel *linphoneCoreVersionLabel;
@property (nonatomic, retain) IBOutlet UIView *contentView;
@property (nonatomic, retain) IBOutlet UILabel *linkLabel;
@property (nonatomic, retain) IBOutlet UILabel *copyrightLabel;
@property (nonatomic, retain) IBOutlet UILabel *licenseLabel;
@property (nonatomic, retain) IBOutlet UIWebView *licensesView;
@property (nonatomic, retain) IBOutlet UITapGestureRecognizer *linkTapGestureRecognizer;
- (IBAction)onLinkTap:(id)sender;
@end

View file

@ -0,0 +1,179 @@
/* AboutViewController.m
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "AboutViewController.h"
#include "ConsoleViewController.h"
#import "LinphoneManager.h"
#include "lpconfig.h"
@implementation AboutViewController
@synthesize linphoneCoreVersionLabel;
@synthesize linphoneLabel;
@synthesize linphoneIphoneVersionLabel;
@synthesize contentView;
@synthesize linkTapGestureRecognizer;
@synthesize linkLabel;
@synthesize licensesView;
@synthesize licenseLabel;
@synthesize copyrightLabel;
#pragma mark - Lifecycle Functions
- (id)init {
self = [super initWithNibName:@"AboutViewController" bundle:[NSBundle mainBundle]];
if (self != nil) {
self->linkTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onLinkTap:)];
}
return self;
}
- (void)dealloc {
[linphoneCoreVersionLabel release];
[linphoneIphoneVersionLabel release];
[contentView release];
[linkTapGestureRecognizer release];
[linkLabel release];
[licensesView release];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[super viewDidLoad];
[linkLabel setText:NSLocalizedString(@"http://www.linphone.org", nil)];
[licenseLabel setText:NSLocalizedString(@"GNU General Public License V2 ", nil)];
[copyrightLabel setText:NSLocalizedString(@"© 2010-2012 Belledonne Communications ", nil)];
[linkLabel addGestureRecognizer:linkTapGestureRecognizer];
UIScrollView *scrollView = (UIScrollView *)self.view;
[scrollView addSubview:contentView];
[scrollView setContentSize:[contentView bounds].size];
[linphoneLabel setText:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]];
[linphoneIphoneVersionLabel setText:[NSString stringWithFormat:@"%@ iPhone %@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]
,[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]];
[linphoneCoreVersionLabel setText:[NSString stringWithFormat:@"%@ Core %s", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"], linphone_core_get_version()]];
if([LinphoneManager runningOnIpad]) {
[LinphoneUtils adjustFontSize:self.view mult:2.22f];
}
[AboutViewController removeBackground:licensesView];
// Create a request to the resource
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:[LinphoneManager bundleFile:@"licenses.html"]]] ;
// Load the resource using the request
[licensesView setDelegate:self];
[licensesView loadRequest:request];
[[AboutViewController defaultScrollView:licensesView] setScrollEnabled:FALSE];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"About"
content:@"AboutViewController"
stateBar:nil
stateBarEnabled:false
tabBar:@"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark -
+ (void)removeBackground:(UIView *)view {
for (UIView *subview in [view subviews]) {
[subview setOpaque:NO];
[subview setBackgroundColor:[UIColor clearColor]];
}
[view setOpaque:NO];
[view setBackgroundColor:[UIColor clearColor]];
}
+ (UIScrollView *)defaultScrollView:(UIWebView *)webView {
UIScrollView *scrollView = nil;
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 5.0) {
return webView.scrollView;
} else {
for (UIView *subview in [webView subviews]) {
if ([subview isKindOfClass:[UIScrollView class]]) {
scrollView = (UIScrollView *)subview;
}
}
}
return scrollView;
}
#pragma mark - Action Functions
- (IBAction)onLinkTap:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:linkLabel.text]];
}
#pragma mark - UIWebViewDelegate Functions
- (void)webViewDidFinishLoad:(UIWebView *)webView {
CGSize size = [webView sizeThatFits:CGSizeMake(self.view.bounds.size.width, 10000.0f)];
float diff = size.height - webView.bounds.size.height;
UIScrollView *scrollView = (UIScrollView *)self.view;
CGRect contentFrame = [contentView bounds];
contentFrame.size.height += diff;
[contentView setAutoresizesSubviews:FALSE];
[contentView setFrame:contentFrame];
[contentView setAutoresizesSubviews:TRUE];
[scrollView setContentSize:contentFrame.size];
CGRect licensesViewFrame = [licensesView frame];
licensesViewFrame.size.height += diff;
[licensesView setFrame:licensesViewFrame];
}
- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if (inType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
}
@end

View file

@ -0,0 +1,603 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">784</int>
<string key="IBDocument.SystemVersion">11E53</string>
<string key="IBDocument.InterfaceBuilderVersion">2844</string>
<string key="IBDocument.AppKitVersion">1138.47</string>
<string key="IBDocument.HIToolboxVersion">569.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1930</string>
</object>
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>IBProxyObject</string>
<string>IBUIImageView</string>
<string>IBUILabel</string>
<string>IBUIScrollView</string>
<string>IBUIView</string>
<string>IBUIWebView</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIScrollView" id="457997634">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIClipsSubviews">YES</bool>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<double key="IBUIContentInset.top">0.0</double>
<double key="IBUIContentInset.bottom">10</double>
<double key="IBUIContentInset.left">0.0</double>
<double key="IBUIContentInset.right">0.0</double>
<bool key="IBUIAlwaysBounceVertical">YES</bool>
<bool key="IBUIShowsHorizontalScrollIndicator">NO</bool>
<double key="IBUIScrollIndicatorInsets.top">0.0</double>
<double key="IBUIScrollIndicatorInsets.bottom">10</double>
<double key="IBUIScrollIndicatorInsets.left">0.0</double>
<double key="IBUIScrollIndicatorInsets.right">0.0</double>
</object>
<object class="IBUIView" id="775128611">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIImageView" id="97290309">
<reference key="NSNextResponder" ref="775128611"/>
<int key="NSvFlags">311</int>
<string key="NSFrame">{{124, 20}, {72, 72}}</string>
<reference key="NSSuperview" ref="775128611"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="945733244"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<int key="IBUIContentMode">1</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">linphone_logo.png</string>
</object>
</object>
<object class="IBUILabel" id="945733244">
<reference key="NSNextResponder" ref="775128611"/>
<int key="NSvFlags">314</int>
<string key="NSFrame">{{10, 100}, {300, 50}}</string>
<reference key="NSSuperview" ref="775128611"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="966549235"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Linphone</string>
<object class="NSColor" key="IBUITextColor" id="549716735">
<int key="NSColorSpace">2</int>
<bytes key="NSRGB">MC4zNTY4NjI3NTM2IDAuMzk2MDc4NDM3NiAwLjQzNTI5NDEyMTUAA</bytes>
</object>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">0</int>
<int key="IBUITextAlignment">1</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">35</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">35</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUILabel" id="55823705">
<reference key="NSNextResponder" ref="775128611"/>
<int key="NSvFlags">314</int>
<string key="NSFrame">{{10, 200}, {300, 44}}</string>
<reference key="NSSuperview" ref="775128611"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="697092436"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">http://www.linphone.org</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">2</int>
<bytes key="NSRGB">MC44MTE3NjQ3MTcxIDAuMjk4MDM5MjI3NyAwLjE2MDc4NDMxOQA</bytes>
</object>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">1</int>
<float key="IBUIMinimumFontSize">10</float>
<int key="IBUITextAlignment">1</int>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="151194520">
<int key="type">1</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont" id="901921461">
<string key="NSName">Helvetica</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUILabel" id="966549235">
<reference key="NSNextResponder" ref="775128611"/>
<int key="NSvFlags">314</int>
<string key="NSFrame">{{10, 150}, {300, 21}}</string>
<reference key="NSSuperview" ref="775128611"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="132342957"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Linphone iPhone 1.0</string>
<reference key="IBUITextColor" ref="549716735"/>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">0</int>
<int key="IBUITextAlignment">1</int>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="741880680">
<int key="type">1</int>
<double key="pointSize">13</double>
</object>
<object class="NSFont" key="IBUIFont" id="141611231">
<string key="NSName">Helvetica</string>
<double key="NSSize">13</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUILabel" id="132342957">
<reference key="NSNextResponder" ref="775128611"/>
<int key="NSvFlags">314</int>
<string key="NSFrame">{{10, 172}, {300, 21}}</string>
<reference key="NSSuperview" ref="775128611"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="55823705"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Linphone Core 1.0</string>
<reference key="IBUITextColor" ref="549716735"/>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">0</int>
<int key="IBUITextAlignment">1</int>
<reference key="IBUIFontDescription" ref="741880680"/>
<reference key="IBUIFont" ref="141611231"/>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUILabel" id="28600489">
<reference key="NSNextResponder" ref="775128611"/>
<int key="NSvFlags">314</int>
<string key="NSFrame">{{10, 300}, {300, 21}}</string>
<reference key="NSSuperview" ref="775128611"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="364833627"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">© 2010-2012 Belledonne Communications </string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
<string key="IBUIColorCocoaTouchKeyPath">darkTextColor</string>
</object>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">1</int>
<float key="IBUIMinimumFontSize">10</float>
<int key="IBUITextAlignment">1</int>
<reference key="IBUIFontDescription" ref="151194520"/>
<reference key="IBUIFont" ref="901921461"/>
</object>
<object class="IBUILabel" id="697092436">
<reference key="NSNextResponder" ref="775128611"/>
<int key="NSvFlags">314</int>
<string key="NSFrame">{{10, 244}, {300, 36}}</string>
<reference key="NSSuperview" ref="775128611"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="28600489"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">GNU General Public License V2 </string>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">0</int>
<int key="IBUINumberOfLines">0</int>
<int key="IBUITextAlignment">1</int>
<reference key="IBUIFontDescription" ref="151194520"/>
<reference key="IBUIFont" ref="901921461"/>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
<double key="preferredMaxLayoutWidth">300</double>
</object>
<object class="IBUIWebView" id="364833627">
<reference key="NSNextResponder" ref="775128611"/>
<int key="NSvFlags">314</int>
<string key="NSFrame">{{10, 380}, {300, 210}}</string>
<reference key="NSSuperview" ref="775128611"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIDataDetectorTypes">2</int>
</object>
</object>
<string key="NSFrameSize">{320, 600}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="97290309"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">linkLabel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="55823705"/>
</object>
<int key="connectionID">60</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="457997634"/>
</object>
<int key="connectionID">63</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">contentView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="775128611"/>
</object>
<int key="connectionID">64</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">linphoneCoreVersionLabel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="132342957"/>
</object>
<int key="connectionID">67</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">linphoneIphoneVersionLabel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="966549235"/>
</object>
<int key="connectionID">68</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">licensesView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="364833627"/>
</object>
<int key="connectionID">70</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">linphoneLabel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="945733244"/>
</object>
<int key="connectionID">71</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">copyrightLabel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="28600489"/>
</object>
<int key="connectionID">72</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">62</int>
<reference key="object" ref="457997634"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">51</int>
<reference key="object" ref="775128611"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="97290309"/>
<reference ref="945733244"/>
<reference ref="132342957"/>
<reference ref="55823705"/>
<reference ref="966549235"/>
<reference ref="697092436"/>
<reference ref="28600489"/>
<reference ref="364833627"/>
</object>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">61</int>
<reference key="object" ref="697092436"/>
<reference key="parent" ref="775128611"/>
<string key="objectName">licenseLabel</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">58</int>
<reference key="object" ref="28600489"/>
<reference key="parent" ref="775128611"/>
<string key="objectName">copyrightLabel</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">57</int>
<reference key="object" ref="55823705"/>
<reference key="parent" ref="775128611"/>
<string key="objectName">linkLabel</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">56</int>
<reference key="object" ref="945733244"/>
<reference key="parent" ref="775128611"/>
<string key="objectName">linphoneLabel</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">55</int>
<reference key="object" ref="97290309"/>
<reference key="parent" ref="775128611"/>
<string key="objectName">iconImageView</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">65</int>
<reference key="object" ref="966549235"/>
<reference key="parent" ref="775128611"/>
<string key="objectName">linphoneIphoneVersionLabel</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">66</int>
<reference key="object" ref="132342957"/>
<reference key="parent" ref="775128611"/>
<string key="objectName">linphoneCoreVersionLabel</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">69</int>
<reference key="object" ref="364833627"/>
<reference key="parent" ref="775128611"/>
<string key="objectName">licenseView</string>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.CustomClassName</string>
<string>-1.IBPluginDependency</string>
<string>-2.CustomClassName</string>
<string>-2.IBPluginDependency</string>
<string>51.IBPluginDependency</string>
<string>55.IBPluginDependency</string>
<string>56.IBPluginDependency</string>
<string>57.IBPluginDependency</string>
<string>58.IBPluginDependency</string>
<string>61.IBPluginDependency</string>
<string>62.IBPluginDependency</string>
<string>65.IBPluginDependency</string>
<string>66.IBPluginDependency</string>
<string>69.IBPluginDependency</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>AboutViewController</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>UIResponder</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
<int key="maxID">72</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">AboutViewController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">onLinkTap:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<string key="NS.key.0">onLinkTap:</string>
<object class="IBActionInfo" key="NS.object.0">
<string key="name">onLinkTap:</string>
<string key="candidateClassName">id</string>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>contentView</string>
<string>copyrightLabel</string>
<string>licenseLabel</string>
<string>licensesView</string>
<string>linkLabel</string>
<string>linkTapGestureRecognizer</string>
<string>linphoneCoreVersionLabel</string>
<string>linphoneIphoneVersionLabel</string>
<string>linphoneLabel</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIView</string>
<string>UILabel</string>
<string>UILabel</string>
<string>UIWebView</string>
<string>UILabel</string>
<string>UITapGestureRecognizer</string>
<string>UILabel</string>
<string>UILabel</string>
<string>UILabel</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>contentView</string>
<string>copyrightLabel</string>
<string>licenseLabel</string>
<string>licensesView</string>
<string>linkLabel</string>
<string>linkTapGestureRecognizer</string>
<string>linphoneCoreVersionLabel</string>
<string>linphoneIphoneVersionLabel</string>
<string>linphoneLabel</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">contentView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">copyrightLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">licenseLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">licensesView</string>
<string key="candidateClassName">UIWebView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">linkLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">linkTapGestureRecognizer</string>
<string key="candidateClassName">UITapGestureRecognizer</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">linphoneCoreVersionLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">linphoneIphoneVersionLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">linphoneLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/AboutViewController.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<integer value="784" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
<integer value="3000" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="NS.key.0">linphone_logo.png</string>
<string key="NS.object.0">{512, 512}</string>
</object>
<string key="IBCocoaTouchPluginVersion">1930</string>
</data>
</archive>

View file

@ -1,48 +0,0 @@
/* LinphoneManager.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <Foundation/Foundation.h>
#include "linphonecore.h"
enum CallDelegateType {
CD_UNDEFINED = 0,
CD_NEW_CALL,
CD_ZRTP,
CD_VIDEO_UPDATE,
CD_STOP_VIDEO_ON_LOW_BATTERY,
CD_TRANSFER_CALL
};
@protocol UIActionSheetCustomDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet ofType:(enum CallDelegateType) type clickedButtonAtIndex:(NSInteger)buttonIndex withUserDatas:(void*) datas;
@end
@interface CallDelegate : NSObject<UIActionSheetDelegate> {
enum CallDelegateType eventType;
LinphoneCall* call;
id<UIActionSheetCustomDelegate> delegate;
NSTimer* timeout;
}
@property (nonatomic) enum CallDelegateType eventType;
@property (nonatomic) LinphoneCall* call;
@property (nonatomic, retain) id delegate;
@property (nonatomic, retain) NSTimer* timeout;
@end

View file

@ -1,67 +0,0 @@
/* LinphoneManager.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "CallDelegate.h"
@implementation CallDelegate
@synthesize eventType;
@synthesize call;
@synthesize delegate;
@synthesize timeout;
-(void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (timeout) {
[timeout invalidate];
timeout = nil;
}
if (eventType == CD_UNDEFINED) {
ms_error("Incorrect usage of CallDelegate/ActionSheet: eventType must be set");
}
[delegate actionSheet:actionSheet ofType:eventType clickedButtonAtIndex:buttonIndex withUserDatas:call];
}
-(void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (timeout) {
[timeout invalidate];
timeout = nil;
}
if (buttonIndex != actionSheet.cancelButtonIndex) return;
if (eventType == CD_UNDEFINED) {
ms_error("Incorrect usage of CallDelegate/ActionSheet: eventType must be set");
}
[delegate actionSheet:actionSheet ofType:eventType clickedButtonAtIndex:buttonIndex withUserDatas:call];
}
-(void) actionSheetCancel:(UIActionSheet *)actionSheet {
if (timeout) {
[timeout invalidate];
timeout = nil;
}
if (eventType == CD_UNDEFINED) {
ms_error("Incorrect usage of CallDelegate/ActionSheet: eventType must be set");
}
[delegate actionSheet:actionSheet ofType:eventType clickedButtonAtIndex:actionSheet.cancelButtonIndex withUserDatas:call];
}
@end

View file

@ -1,253 +0,0 @@
/* CallHistoryTableViewController.m
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "CallHistoryTableViewController.h"
#import "LinphoneManager.h"
@implementation CallHistoryTableViewController
@synthesize clear;
/*
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
if (self = [super initWithStyle:style]) {
}
return self;
}
*/
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem* clearButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemTrash
target:self
action:@selector(doAction:)];
[self.navigationItem setRightBarButtonItem:clearButton];
[clearButton release];
}
/*
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
*/
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (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;
}
-(void) doAction:(id)sender {
linphone_core_clear_call_logs([LinphoneManager getLc]);
[self.tableView reloadData];
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]);
return ms_list_size(logs);
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
[cell.textLabel setTextColor:[UIColor colorWithRed:0.7 green:0.745 blue:0.78 alpha:1.0]];
[cell.detailTextLabel setTextColor:cell.textLabel.textColor];
}
// Set up the cell...
LinphoneAddress* partyToDisplay;
const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]);
LinphoneCallLog* callLogs = ms_list_nth_data(logs, indexPath.row) ;
NSString *path;
if (callLogs->dir == LinphoneCallIncoming) {
if (callLogs->status == LinphoneCallSuccess) {
path = [[NSBundle mainBundle] pathForResource:callLogs->video_enabled?@"in_call_video":@"in_call" ofType:@"png"];
} else {
//missed call
path = [[NSBundle mainBundle] pathForResource:@"missed_call" ofType:@"png"];
}
partyToDisplay=callLogs->from;
} else {
path = [[NSBundle mainBundle] pathForResource:callLogs->video_enabled?@"out_call_video":@"out_call" ofType:@"png"];
partyToDisplay=callLogs->to;
}
UIImage *image = [UIImage imageWithContentsOfFile:path];
cell.imageView.image = image;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
const char* username = linphone_address_get_username(partyToDisplay)!=0?linphone_address_get_username(partyToDisplay):"";
const char* displayName = linphone_address_get_display_name(partyToDisplay);
if (displayName) {
NSString* str1 = [NSString stringWithFormat:@"%s", displayName];
[cell.textLabel setText:str1];
NSString* str2 = [NSString stringWithFormat:@"%s"/* [%s]"*/,username/*,callLogs->start_date*/];
[cell.detailTextLabel setText:str2];
} else {
NSString* str1 = [NSString stringWithFormat:@"%s", username];
[cell.textLabel setText:str1];
[cell.detailTextLabel setText:nil];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
// AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
// [self.navigationController pushViewController:anotherViewController];
// [anotherViewController release];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]);
LinphoneCallLog* callLogs = ms_list_nth_data(logs, indexPath.row) ;
LinphoneAddress* partyToCall;
if (callLogs->dir == LinphoneCallIncoming) {
partyToCall=callLogs->from;
} else {
partyToCall=callLogs->to;
}
const char* username = linphone_address_get_username(partyToCall)!=0?linphone_address_get_username(partyToCall):"";
const char* displayName = linphone_address_get_display_name(partyToCall)!=0?linphone_address_get_display_name(partyToCall):"";
const char* domain = linphone_address_get_domain(partyToCall);
LinphoneProxyConfig* proxyCfg;
linphone_core_get_default_proxy([LinphoneManager getLc],&proxyCfg);
NSString* phoneNumber;
if (proxyCfg && (strcmp(domain, linphone_proxy_config_get_domain(proxyCfg)) == 0)) {
phoneNumber = [[NSString alloc] initWithCString:username encoding:[NSString defaultCStringEncoding]];
} else {
phoneNumber = [[NSString alloc] initWithCString:linphone_address_as_string_uri_only(partyToCall) encoding:[NSString defaultCStringEncoding]];
}
NSString* dispName = [[NSString alloc] initWithCString:displayName encoding:[NSString defaultCStringEncoding]];
[[LinphoneManager instance].callDelegate displayDialerFromUI:self
forUser:phoneNumber
withDisplayName:dispName];
[phoneNumber release];
[dispName release];
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
- (void)dealloc {
[super dealloc];
}
@end

View file

@ -1,201 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">784</int>
<string key="IBDocument.SystemVersion">9L31a</string>
<string key="IBDocument.InterfaceBuilderVersion">680</string>
<string key="IBDocument.AppKitVersion">949.54</string>
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="4"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
</object>
<object class="IBUITableView" id="873029372">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<bool key="IBUIBouncesZoom">NO</bool>
<int key="IBUISeparatorStyle">1</int>
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
<float key="IBUIRowHeight">4.400000e+01</float>
<float key="IBUISectionHeaderHeight">4.400000e+01</float>
<float key="IBUISectionFooterHeight">2.200000e+01</float>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="873029372"/>
</object>
<int key="connectionID">5</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">dataSource</string>
<reference key="source" ref="873029372"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">6</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="873029372"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">7</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="829125109">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="829125109"/>
<string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="829125109"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="873029372"/>
<reference key="parent" ref="829125109"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.CustomClassName</string>
<string>-2.CustomClassName</string>
<string>4.IBEditorWindowLastContentRect</string>
<string>4.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>CallHistoryTableViewController</string>
<string>UIResponder</string>
<string>{{163, 500}, {320, 480}}</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">13</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">CallHistoryTableViewController</string>
<string key="superclassName">GenericTabViewController</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">doAction:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">clear</string>
<string key="NS.object.0">UIButton</string>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">Classes/CallHistoryTableViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">GenericTabViewController</string>
<string key="superclassName">UITableViewController</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>header</string>
<string>linphoneDelegate</string>
<string>phoneControllerDelegate</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIView</string>
<string>id</string>
<string>id</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">Classes/GenericTabViewController.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.LastKnownRelativeProjectPath">../linphone.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">3.1</string>
</data>
</archive>

View file

@ -0,0 +1,44 @@
/* ChatRoomTableViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "ChatModel.h"
@protocol ChatRoomDelegate <NSObject>
- (BOOL)chatRoomStartImageDownload:(NSURL*)url userInfo:(id)userInfo;
- (BOOL)chatRoomStartImageUpload:(UIImage*)image url:(NSURL*)url;
@end
@interface ChatRoomTableViewController : UITableViewController {
@private
NSMutableArray *data;
}
@property (nonatomic, copy) NSString *remoteAddress;
@property (nonatomic, retain) id<ChatRoomDelegate> chatRoomDelegate;
- (void)addChatEntry:(ChatModel*)chat;
- (void)scrollToBottom:(BOOL)animated;
- (void)scrollToLastUnread:(BOOL)animated;
- (void)updateChatEntry:(ChatModel*)chat;
@end

View file

@ -0,0 +1,193 @@
/* ChatRoomTableViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "LinphoneManager.h"
#import "ChatRoomTableViewController.h"
#import "UIChatRoomCell.h"
#import "Utils.h"
#import "PhoneMainView.h"
#import <NinePatch.h>
@implementation ChatRoomTableViewController
@synthesize remoteAddress;
@synthesize chatRoomDelegate;
#pragma mark - Lifecycle Functions
- (void)dealloc {
[remoteAddress release];
[chatRoomDelegate release];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[TUNinePatchCache flushCache]; // Clear cache
if(data != nil) {
[data removeAllObjects];
[data release];
data = nil;
}
}
- (void)viewWillAppear:(BOOL)animated {
[self loadData];
}
#pragma mark -
- (void)loadData {
if(data != nil) {
[data removeAllObjects];
[data release];
}
data = [[ChatModel listMessages:remoteAddress] retain];
[[self tableView] reloadData];
[self scrollToLastUnread:false];
}
- (void)addChatEntry:(ChatModel*)chat {
if(data == nil) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot add entry: null data"];
return;
}
[self.tableView beginUpdates];
int pos = [data count];
[data insertObject:chat atIndex:pos];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:pos inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
}
- (void)updateChatEntry:(ChatModel*)chat {
if(data == nil) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update entry: null data"];
return;
}
NSInteger index = [data indexOfObject:chat];
if (index<0) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"chat entries diesn not exixt"];
return;
}
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:FALSE];; //just reload
return;
}
- (void)scrollToBottom:(BOOL)animated {
CGSize size = [self.tableView contentSize];
CGRect bounds = [self.tableView bounds];
bounds.origin.y = size.height - bounds.size.height;
[self.tableView.layer removeAllAnimations];
[self.tableView scrollRectToVisible:bounds animated:animated];
}
- (void)scrollToLastUnread:(BOOL)animated {
if(data == nil) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot add entry: null data"];
return;
}
int index = -1;
// Find first unread & set all entry read
for(int i = 0; i <[data count]; ++i) {
ChatModel *chat = [data objectAtIndex:i];
if([[chat read] intValue] == 0) {
[chat setRead:[NSNumber numberWithInt:1]];
if(index == -1)
index = i;
}
}
if(index == -1) {
index = [data count] - 1;
}
// Scroll to unread
if(index >= 0) {
[self.tableView.layer removeAllAnimations];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]
atScrollPosition:UITableViewScrollPositionTop
animated:animated];
}
}
#pragma mark - Property Functions
- (void)setRemoteAddress:(NSString *)aremoteAddress {
if(remoteAddress != nil) {
[remoteAddress release];
}
self->remoteAddress = [aremoteAddress copy];
[self loadData];
}
#pragma mark - UITableViewDataSource Functions
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"UIChatRoomCell";
UIChatRoomCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[[UIChatRoomCell alloc] initWithIdentifier:kCellId] autorelease];
}
[cell setChat:[data objectAtIndex:[indexPath row]]];
[cell setChatRoomDelegate:chatRoomDelegate];
return cell;
}
#pragma mark - UITableViewDelegate Functions
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
ChatModel *chat = [data objectAtIndex:[indexPath row]];
[data removeObjectAtIndex:[indexPath row]];
[chat delete];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
// Detemine if it's in editing mode
if (self.editing) {
return UITableViewCellEditingStyleDelete;
}
return UITableViewCellEditingStyleNone;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
ChatModel *chat = [data objectAtIndex:[indexPath row]];
return [UIChatRoomCell height:chat width:[self.view frame].size.width];
}
@end

View file

@ -0,0 +1,68 @@
/* ChatRoomViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UIToggleButton.h"
#import "UICompositeViewController.h"
#import "ChatRoomTableViewController.h"
#import "HPGrowingTextView.h"
#import "ChatModel.h"
#import "ImagePickerViewController.h"
#import "ImageSharing.h"
#import "OrderedDictionary.h"
#include "linphonecore.h"
@interface ChatRoomViewController : UIViewController<HPGrowingTextViewDelegate, UICompositeViewDelegate, ImagePickerDelegate, ImageSharingDelegate, ChatRoomDelegate> {
LinphoneChatRoom *chatRoom;
ImageSharing *imageSharing;
OrderedDictionary *imageQualities;
BOOL scrollOnGrowingEnabled;
}
@property (nonatomic, retain) IBOutlet ChatRoomTableViewController* tableController;
@property (nonatomic, retain) IBOutlet UIToggleButton *editButton;
@property (nonatomic, retain) IBOutlet HPGrowingTextView* messageField;
@property (nonatomic, retain) IBOutlet UIButton* sendButton;
@property (nonatomic, retain) IBOutlet UILabel *addressLabel;
@property (nonatomic, retain) IBOutlet UIImageView *avatarImage;
@property (nonatomic, retain) IBOutlet UIView *headerView;
@property (nonatomic, retain) IBOutlet UIView *chatView;
@property (nonatomic, retain) IBOutlet UIView *messageView;
@property (nonatomic, retain) IBOutlet UIImageView *messageBackgroundImage;
@property (nonatomic, retain) IBOutlet UIImageView *transferBackgroundImage;
@property (nonatomic, retain) IBOutlet UITapGestureRecognizer *listTapGestureRecognizer;
@property (nonatomic, copy) NSString *remoteAddress;
@property (nonatomic, retain) IBOutlet UIButton* pictureButton;
@property (nonatomic, retain) IBOutlet UIButton* cancelTransferButton;
@property (nonatomic, retain) IBOutlet UIProgressView* imageTransferProgressBar;
@property (nonatomic, retain) IBOutlet UIView* transferView;
@property (nonatomic, retain) IBOutlet UIView* waitView;
- (IBAction)onBackClick:(id)event;
- (IBAction)onEditClick:(id)event;
- (IBAction)onMessageChange:(id)sender;
- (IBAction)onSendClick:(id)event;
- (IBAction)onPictureClick:(id)event;
- (IBAction)onTransferCancelClick:(id)event;
- (IBAction)onListTap:(id)sender;
@end

View file

@ -0,0 +1,788 @@
/* ChatRoomViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ChatRoomViewController.h"
#import "PhoneMainView.h"
#import "DTActionSheet.h"
#import "UILinphone.h"
#import <NinePatch.h>
#import <MobileCoreServices/UTCoreTypes.h>
#import "Utils.h"
@implementation ChatRoomViewController
@synthesize tableController;
@synthesize sendButton;
@synthesize messageField;
@synthesize editButton;
@synthesize remoteAddress;
@synthesize addressLabel;
@synthesize avatarImage;
@synthesize headerView;
@synthesize chatView;
@synthesize messageView;
@synthesize messageBackgroundImage;
@synthesize transferBackgroundImage;
@synthesize listTapGestureRecognizer;
@synthesize pictureButton;
@synthesize imageTransferProgressBar;
@synthesize cancelTransferButton;
@synthesize transferView;
@synthesize waitView;
#pragma mark - Lifecycle Functions
- (id)init {
self = [super initWithNibName:@"ChatRoomViewController" bundle:[NSBundle mainBundle]];
if (self != nil) {
self->scrollOnGrowingEnabled = TRUE;
self->chatRoom = NULL;
self->imageSharing = NULL;
self->listTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onListTap:)];
self->imageQualities = [[OrderedDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithFloat:0.9], NSLocalizedString(@"Maximum", nil),
[NSNumber numberWithFloat:0.5], NSLocalizedString(@"Average", nil),
[NSNumber numberWithFloat:0.0], NSLocalizedString(@"Minimum", nil), nil];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[tableController release];
[messageField release];
[sendButton release];
[editButton release];
[remoteAddress release];
[addressLabel release];
[avatarImage release];
[headerView release];
[messageView release];
[messageBackgroundImage release];
[transferBackgroundImage release];
[listTapGestureRecognizer release];
[transferView release];
[pictureButton release];
[imageTransferProgressBar release];
[cancelTransferButton release];
[imageQualities release];
[waitView release];
[super dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"ChatRoom"
content:@"ChatRoomViewController"
stateBar:nil
stateBarEnabled:false
tabBar:/*@"UIMainBar"*/nil
tabBarEnabled:false /*to keep room for chat*/
fullscreen:false
landscapeMode:true
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[super viewDidLoad];
[tableController setChatRoomDelegate:self];
// Set selected+over background: IB lack !
[editButton setBackgroundImage:[UIImage imageNamed:@"chat_ok_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:editButton];
messageField.minNumberOfLines = 1;
messageField.maxNumberOfLines = ([LinphoneManager runningOnIpad])?10:3;
messageField.delegate = self;
messageField.font = [UIFont systemFontOfSize:18.0f];
messageField.contentInset = UIEdgeInsetsMake(0, -5, -2, -5);
messageField.internalTextView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 10);
messageField.backgroundColor = [UIColor clearColor];
[sendButton setEnabled:FALSE];
[tableController.tableView addGestureRecognizer:listTapGestureRecognizer];
[listTapGestureRecognizer setEnabled:FALSE];
[tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
[tableController.tableView setBackgroundView:nil];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillEnterForeground:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textReceivedEvent:)
name:kLinphoneTextReceived
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onMessageChange:)
name:UITextViewTextDidChangeNotification
object:nil];
if([tableController isEditing])
[tableController setEditing:FALSE animated:FALSE];
[editButton setOff];
[[tableController tableView] reloadData];
[messageBackgroundImage setImage:[TUNinePatchCache imageOfSize:[messageBackgroundImage bounds].size
forNinePatchNamed:@"chat_message_background"]];
BOOL fileSharingEnabled = [[LinphoneManager instance] lpConfigStringForKey:@"sharing_server_preference"] != NULL
&& [[[LinphoneManager instance] lpConfigStringForKey:@"sharing_server_preference"] length]>0;
[pictureButton setEnabled:fileSharingEnabled];
[waitView setHidden:TRUE];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if(imageSharing) {
[imageSharing cancel];
}
[messageField resignFirstResponder];
if(chatRoom != NULL) {
linphone_chat_room_destroy(chatRoom);
chatRoom = NULL;
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneTextReceived
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UITextViewTextDidChangeNotification
object:nil];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
[messageBackgroundImage setImage:[TUNinePatchCache imageOfSize:[messageBackgroundImage bounds].size
forNinePatchNamed:@"chat_message_background"]];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
-(void)didReceiveMemoryWarning {
[TUNinePatchCache flushCache]; // will remove any images cache (freeing any cached but unused images)
}
#pragma mark -
- (void)setRemoteAddress:(NSString*)aRemoteAddress {
if(remoteAddress != nil) {
[remoteAddress release];
}
remoteAddress = [aRemoteAddress copy];
[messageField setText:@""];
[self update];
[tableController setRemoteAddress: remoteAddress];
[ChatModel readConversation:remoteAddress];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
}
- (void)applicationWillEnterForeground:(NSNotification*)notif {
if(remoteAddress != nil) {
[ChatModel readConversation:remoteAddress];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
}
}
- (void)update {
if(remoteAddress == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room header: null contact"];
return;
}
NSString *displayName = nil;
UIImage *image = nil;
LinphoneAddress* linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], [remoteAddress UTF8String]);
if (linphoneAddress == NULL) {
[[PhoneMainView instance] popCurrentView];
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid SIP address",nil)
message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to send a message or use a valid SIP address (I.E sip:john@example.net)",nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil];
[error show];
[error release];
return;
}
char *tmp = linphone_address_as_string_uri_only(linphoneAddress);
NSString *normalizedSipAddress = [NSString stringWithUTF8String:tmp];
ms_free(tmp);
ABRecordRef acontact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress];
if(acontact != nil) {
displayName = [FastAddressBook getContactDisplayName:acontact];
image = [FastAddressBook getContactImage:acontact thumbnail:true];
}
[remoteAddress release];
remoteAddress = [normalizedSipAddress retain];
// Display name
if(displayName == nil) {
displayName = [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)];
}
[addressLabel setText:displayName];
// Avatar
if(image == nil) {
image = [UIImage imageNamed:@"avatar_unknown_small.png"];
}
[avatarImage setImage:image];
linphone_address_destroy(linphoneAddress);
}
static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud) {
ChatRoomViewController* thiz = (ChatRoomViewController*)ud;
ChatModel *chat = (ChatModel *)linphone_chat_message_get_user_data(msg);
[LinphoneLogger log:LinphoneLoggerLog
format:@"Delivery status for [%@] is [%s]",(chat.message?chat.message:@""),linphone_chat_message_state_to_string(state)];
[chat setState:[NSNumber numberWithInt:state]];
[chat update];
[thiz.tableController updateChatEntry:chat];
linphone_chat_message_set_user_data(msg, NULL);
[chat release]; // no longuer need to keep reference
}
- (BOOL)sendMessage:(NSString *)message withExterlBodyUrl:(NSURL*)externalUrl withInternalUrl:(NSURL*)internalUrl {
if(![LinphoneManager isLcReady]) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot send message: Linphone core not ready"];
return FALSE;
}
if(remoteAddress == nil) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot send message: Null remoteAddress"];
return FALSE;
}
if(chatRoom == NULL) {
chatRoom = linphone_core_create_chat_room([LinphoneManager getLc], [remoteAddress UTF8String]);
}
// Save message in database
ChatModel *chat = [[ChatModel alloc] init];
[chat setRemoteContact:remoteAddress];
[chat setLocalContact:@""];
if(internalUrl == nil) {
[chat setMessage:message];
} else {
[chat setMessage:[internalUrl absoluteString]];
}
[chat setDirection:[NSNumber numberWithInt:0]];
[chat setTime:[NSDate date]];
[chat setRead:[NSNumber numberWithInt:1]];
[chat setState:[NSNumber numberWithInt:1]]; //INPROGRESS
[chat create];
[tableController addChatEntry:chat];
[tableController scrollToBottom:TRUE];
[chat release];
LinphoneChatMessage* msg = linphone_chat_room_create_message(chatRoom, [message UTF8String]);
linphone_chat_message_set_user_data(msg, [chat retain]);
if(externalUrl) {
linphone_chat_message_set_external_body_url(msg, [[externalUrl absoluteString] UTF8String]);
}
linphone_chat_room_send_message2(chatRoom, msg, message_status, self);
return TRUE;
}
- (void)saveAndSend:(UIImage*)image url:(NSURL*)url {
if(url == nil) {
[waitView setHidden:FALSE];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[LinphoneManager instance].photoLibrary writeImageToSavedPhotosAlbum:image.CGImage
orientation:(ALAssetOrientation)[image imageOrientation]
completionBlock:^(NSURL *assetURL, NSError *error){
dispatch_async(dispatch_get_main_queue(), ^{
[waitView setHidden:TRUE];
if (error) {
[LinphoneLogger log:LinphoneLoggerError format:@"Cannot save image data downloaded [%@]", [error localizedDescription]];
UIAlertView* errorAlert = [UIAlertView alloc];
[errorAlert initWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot write image to photo library", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Ok",nil)
otherButtonTitles:nil ,nil];
[errorAlert show];
[errorAlert release];
return;
}
[LinphoneLogger log:LinphoneLoggerLog format:@"Image saved to [%@]", [assetURL absoluteString]];
[self chatRoomStartImageUpload:image url:assetURL];
});
}];
});
} else {
[self chatRoomStartImageUpload:image url:url];
}
}
- (void)chooseImageQuality:(UIImage*)image url:(NSURL*)url {
[waitView setHidden:FALSE];
DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Choose the image size", nil)];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//UIImage *image = [original_image normalizedImage];
for(NSString *key in [imageQualities allKeys]) {
NSNumber *number = [imageQualities objectForKey:key];
NSData *data = UIImageJPEGRepresentation(image, [number floatValue]);
NSNumber *size = [NSNumber numberWithInteger:[data length]];
NSString *text = [NSString stringWithFormat:@"%@ (%@)", key, [size toHumanReadableSize]];
[sheet addButtonWithTitle:text block:^(){
[self saveAndSend:[UIImage imageWithData:data] url:url];
}];
}
[sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
dispatch_async(dispatch_get_main_queue(), ^{
[waitView setHidden:TRUE];
[sheet showInView:[PhoneMainView instance].view];
});
});
}
#pragma mark - Event Functions
- (void)textReceivedEvent:(NSNotification *)notif {
//LinphoneChatRoom *room = [[[notif userInfo] objectForKey:@"room"] pointerValue];
//NSString *message = [[notif userInfo] objectForKey:@"message"];
LinphoneAddress *from = [[[notif userInfo] objectForKey:@"from"] pointerValue];
ChatModel *chat = [[notif userInfo] objectForKey:@"chat"];
if(from == NULL || chat == NULL) {
return;
}
char *fromStr = linphone_address_as_string_uri_only(from);
if(fromStr != NULL) {
if([[NSString stringWithUTF8String:fromStr]
caseInsensitiveCompare:remoteAddress] == NSOrderedSame) {
if (![[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
|| [UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
[chat setRead:[NSNumber numberWithInt:1]];
[chat update];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
}
[tableController addChatEntry:chat];
[tableController scrollToLastUnread:TRUE];
}
ms_free(fromStr);
}
}
#pragma mark - UITextFieldDelegate Functions
- (BOOL)growingTextViewShouldBeginEditing:(HPGrowingTextView *)growingTextView {
if(editButton.selected) {
[tableController setEditing:FALSE animated:TRUE];
[editButton setOff];
}
[listTapGestureRecognizer setEnabled:TRUE];
return TRUE;
}
- (BOOL)growingTextViewShouldEndEditing:(HPGrowingTextView *)growingTextView {
[listTapGestureRecognizer setEnabled:FALSE];
return TRUE;
}
- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height {
int diff = height - growingTextView.bounds.size.height;
if(diff != 0) {
CGRect messageRect = [messageView frame];
messageRect.origin.y -= diff;
messageRect.size.height += diff;
[messageView setFrame:messageRect];
// Always stay at bottom
if(scrollOnGrowingEnabled) {
CGRect tableFrame = [tableController.view frame];
CGPoint contentPt = [tableController.tableView contentOffset];
contentPt.y += diff;
if(contentPt.y + tableFrame.size.height > tableController.tableView.contentSize.height)
contentPt.y += diff;
[tableController.tableView setContentOffset:contentPt animated:FALSE];
}
CGRect tableRect = [tableController.view frame];
tableRect.size.height -= diff;
[tableController.view setFrame:tableRect];
[messageBackgroundImage setImage:[TUNinePatchCache imageOfSize:[messageBackgroundImage bounds].size
forNinePatchNamed:@"chat_message_background"]];
}
}
#pragma mark - Action Functions
- (IBAction)onBackClick:(id)event {
[[PhoneMainView instance] popCurrentView];
}
- (IBAction)onEditClick:(id)event {
[tableController setEditing:![tableController isEditing] animated:TRUE];
[messageField resignFirstResponder];
}
- (IBAction)onSendClick:(id)event {
if([self sendMessage:[messageField text] withExterlBodyUrl:nil withInternalUrl:nil]) {
scrollOnGrowingEnabled = FALSE;
[messageField setText:@""];
scrollOnGrowingEnabled = TRUE;
[self onMessageChange:nil];
}
}
- (IBAction)onListTap:(id)sender {
[messageField resignFirstResponder];
}
- (IBAction)onMessageChange:(id)sender {
if([[messageField text] length] > 0) {
[sendButton setEnabled:TRUE];
} else {
[sendButton setEnabled:FALSE];
}
}
- (IBAction)onPictureClick:(id)event {
[messageField resignFirstResponder];
void (^block)(UIImagePickerControllerSourceType) = ^(UIImagePickerControllerSourceType type) {
UICompositeViewDescription *description = [ImagePickerViewController compositeViewDescription];
ImagePickerViewController *controller;
if([LinphoneManager runningOnIpad]) {
controller = DYNAMIC_CAST([[PhoneMainView instance].mainViewController getCachedController:description.content], ImagePickerViewController);
} else {
controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:description push:TRUE], ImagePickerViewController);
}
if(controller != nil) {
controller.sourceType = type;
// Displays a control that allows the user to choose picture or
// movie capture, if both are available:
controller.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
controller.allowsEditing = NO;
controller.imagePickerDelegate = self;
if([LinphoneManager runningOnIpad]) {
CGRect rect = [self.messageView convertRect:[pictureButton frame] toView:self.view];
[controller.popoverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:FALSE];
}
}
};
DTActionSheet *sheet = [[[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Select picture source",nil)] autorelease];
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
[sheet addButtonWithTitle:NSLocalizedString(@"Camera",nil) block:^(){
block(UIImagePickerControllerSourceTypeCamera);
}];
}
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
[sheet addButtonWithTitle:NSLocalizedString(@"Photo library",nil) block:^(){
block(UIImagePickerControllerSourceTypePhotoLibrary);
}];
}
[sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel",nil)];
[sheet showInView:[PhoneMainView instance].view];
}
- (IBAction)onTransferCancelClick:(id)event {
if(imageSharing) {
[imageSharing cancel];
}
}
#pragma mark ChatRoomDelegate
- (BOOL)chatRoomStartImageDownload:(NSURL*)url userInfo:(id)userInfo {
if(imageSharing == nil) {
imageSharing = [ImageSharing imageSharingDownload:url delegate:self userInfo:userInfo];
[messageView setHidden:TRUE];
[transferView setHidden:FALSE];
return TRUE;
}
return FALSE;
}
- (BOOL)chatRoomStartImageUpload:(UIImage*)image url:(NSURL*)url{
if(imageSharing == nil) {
NSString *urlString = [[LinphoneManager instance] lpConfigStringForKey:@"sharing_server_preference"];
imageSharing = [ImageSharing imageSharingUpload:[NSURL URLWithString:urlString] image:image delegate:self userInfo:url];
[messageView setHidden:TRUE];
[transferView setHidden:FALSE];
return TRUE;
}
return FALSE;
}
#pragma mark ImageSharingDelegate
- (void)imageSharingProgress:(ImageSharing*)aimageSharing progress:(float)progress {
[imageTransferProgressBar setProgress:progress];
}
- (void)imageSharingAborted:(ImageSharing*)aimageSharing {
[messageView setHidden:FALSE];
[transferView setHidden:TRUE];
imageSharing = NULL;
}
- (void)imageSharingError:(ImageSharing*)aimageSharing error:(NSError *)error {
[messageView setHidden:FALSE];
[transferView setHidden:TRUE];
NSString *url = [aimageSharing.connection.currentRequest.URL absoluteString];
if (aimageSharing.upload) {
[LinphoneLogger log:LinphoneLoggerError format:@"Cannot upload file to server [%@] because [%@]", url, [error localizedDescription]];
UIAlertView* errorAlert = [UIAlertView alloc];
[errorAlert initWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot transfer file to remote contact", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Ok",nil)
otherButtonTitles:nil ,nil];
[errorAlert show];
[errorAlert release];
} else {
[LinphoneLogger log:LinphoneLoggerError format:@"Cannot dowanlod file from [%@] because [%@]", url, [error localizedDescription]];
UIAlertView* errorAlert = [UIAlertView alloc];
[errorAlert initWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot transfer file from remote contact", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue", nil)
otherButtonTitles:nil, nil];
[errorAlert show];
[errorAlert release];
}
imageSharing = NULL;
}
- (void)imageSharingUploadDone:(ImageSharing*)aimageSharing url:(NSURL*)url{
NSURL *imageURL = [aimageSharing userInfo];
[self sendMessage:nil withExterlBodyUrl:url withInternalUrl:imageURL];
[messageView setHidden:FALSE];
[transferView setHidden:TRUE];
imageSharing = NULL;
}
- (void)imageSharingDownloadDone:(ImageSharing*)aimageSharing image:(UIImage *)image {
[messageView setHidden:FALSE];
[transferView setHidden:TRUE];
ChatModel *chat = (ChatModel *)[imageSharing userInfo];
[[LinphoneManager instance].photoLibrary writeImageToSavedPhotosAlbum:image.CGImage
orientation:(ALAssetOrientation)[image imageOrientation]
completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
[LinphoneLogger log:LinphoneLoggerError format:@"Cannot save image data downloaded [%@]", [error localizedDescription]];
UIAlertView* errorAlert = [UIAlertView alloc];
[errorAlert initWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot write image to photo library", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Ok",nil)
otherButtonTitles:nil ,nil];
[errorAlert show];
[errorAlert release];
return;
}
[LinphoneLogger log:LinphoneLoggerLog format:@"Image saved to [%@]", [assetURL absoluteString]];
[chat setMessage:[assetURL absoluteString]];
[chat update];
[tableController updateChatEntry:chat];
}];
imageSharing = NULL;
}
#pragma mark ImagePickerDelegate
- (void)imagePickerDelegateImage:(UIImage*)image info:(NSDictionary *)info {
// Dismiss popover on iPad
if([LinphoneManager runningOnIpad]) {
UICompositeViewDescription *description = [ImagePickerViewController compositeViewDescription];
ImagePickerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance].mainViewController getCachedController:description.content], ImagePickerViewController);
if(controller != nil) {
[controller.popoverController dismissPopoverAnimated:TRUE];
}
}
NSURL *url = [info valueForKey:UIImagePickerControllerReferenceURL];
[self chooseImageQuality:image url:url];
}
#pragma mark - Keyboard Event Functions
- (void)keyboardWillHide:(NSNotification *)notif {
//CGRect beginFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
//CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
UIViewAnimationCurve curve = [[[notif userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView beginAnimations:@"resize" context:nil];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:TRUE];
// Resize chat view
{
CGRect chatFrame = [[self chatView] frame];
chatFrame.size.height = [[self view] frame].size.height - chatFrame.origin.y;
[[self chatView] setFrame:chatFrame];
}
// Move header view
{
CGRect headerFrame = [headerView frame];
headerFrame.origin.y = 0;
[headerView setFrame:headerFrame];
}
// Resize & Move table view
{
CGRect tableFrame = [tableController.view frame];
tableFrame.origin.y = [headerView frame].origin.y + [headerView frame].size.height;
double diff = tableFrame.size.height;
tableFrame.size.height = [messageView frame].origin.y - tableFrame.origin.y;
diff = tableFrame.size.height - diff;
[tableController.view setFrame:tableFrame];
// Always stay at bottom
CGPoint contentPt = [tableController.tableView contentOffset];
contentPt.y -= diff;
if(contentPt.y + tableFrame.size.height > tableController.tableView.contentSize.height)
contentPt.y += diff;
[tableController.tableView setContentOffset:contentPt animated:FALSE];
}
[UIView commitAnimations];
}
- (void)keyboardWillShow:(NSNotification *)notif {
//CGRect beginFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
UIViewAnimationCurve curve = [[[notif userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView beginAnimations:@"resize" context:nil];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:TRUE];
if(UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
int width = endFrame.size.height;
endFrame.size.height = endFrame.size.width;
endFrame.size.width = width;
}
// Resize chat view
{
CGRect viewFrame = [[self view] frame];
CGRect rect = [PhoneMainView instance].view.bounds;
CGPoint pos = {viewFrame.size.width, viewFrame.size.height};
CGPoint gPos = [self.view convertPoint:pos toView:[UIApplication sharedApplication].keyWindow.rootViewController.view]; // Bypass IOS bug on landscape mode
float diff = (rect.size.height - gPos.y - endFrame.size.height);
if(diff > 0) diff = 0;
CGRect chatFrame = [[self chatView] frame];
chatFrame.size.height = viewFrame.size.height - chatFrame.origin.y + diff;
[[self chatView] setFrame:chatFrame];
}
// Move header view
{
CGRect headerFrame = [headerView frame];
headerFrame.origin.y = -headerFrame.size.height;
[headerView setFrame:headerFrame];
}
// Resize & Move table view
{
CGRect tableFrame = [tableController.view frame];
tableFrame.origin.y = [headerView frame].origin.y + [headerView frame].size.height;
tableFrame.size.height = [messageView frame].origin.y - tableFrame.origin.y;
[tableController.view setFrame:tableFrame];
}
// Scroll
int lastSection = [tableController.tableView numberOfSections] - 1;
if(lastSection >= 0) {
int lastRow = [tableController.tableView numberOfRowsInSection:lastSection] - 1;
if(lastRow >=0) {
[tableController.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:lastRow inSection:lastSection]
atScrollPosition:UITableViewScrollPositionBottom
animated:TRUE];
}
}
[UIView commitAnimations];
}
@end

View file

@ -1,6 +1,6 @@
/* UIDuration.h
/* ChatTableViewController.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,19 +15,15 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
*/
#import <UIKit/UIKit.h>
@interface UIDuration : UILabel {
@private
NSTimer *durationRefreasher;
@interface ChatTableViewController : UITableViewController {
@private
NSMutableArray *data;
}
-(void) start;
-(void) stop;
- (void)loadData;
@end

View file

@ -0,0 +1,120 @@
/* ChatTableViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ChatTableViewController.h"
#import "UIChatCell.h"
#import "linphonecore.h"
#import "PhoneMainView.h"
#import "UACellBackgroundView.h"
#import "UILinphone.h"
#import "Utils.h"
@implementation ChatTableViewController
#pragma mark - Lifecycle Functions
- (void)dealloc {
if(data != nil)
[data release];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self loadData];
}
#pragma mark -
- (void)loadData {
if(data != nil)
[data release];
data = [[ChatModel listConversations] retain];
[[self tableView] reloadData];
}
#pragma mark - UITableViewDataSource Functions
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"UIChatCell";
UIChatCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[[UIChatCell alloc] initWithIdentifier:kCellId] autorelease];
// Background View
UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView = selectedBackgroundView;
[selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR];
}
[cell setChat:[data objectAtIndex:[indexPath row]]];
return cell;
}
#pragma mark - UITableViewDelegate Functions
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
ChatModel *chat = [data objectAtIndex:[indexPath row]];
// Go to ChatRoom view
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
if(controller != nil) {
[controller setRemoteAddress:[chat remoteContact]];
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
// Detemine if it's in editing mode
if (self.editing) {
return UITableViewCellEditingStyleDelete;
}
return UITableViewCellEditingStyleNone;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
ChatModel *chat = [data objectAtIndex:[indexPath row]];
[ChatModel removeConversation:[chat remoteContact]];
[data removeObjectAtIndex:[indexPath row]];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
}
}
@end

View file

@ -0,0 +1,37 @@
/* ChatViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UIToggleButton.h"
#import "ChatTableViewController.h"
#import "UICompositeViewController.h"
@interface ChatViewController : UIViewController<UITextFieldDelegate,UICompositeViewDelegate> {
}
@property (nonatomic, retain) IBOutlet ChatTableViewController* tableController;
@property (nonatomic, retain) IBOutlet UIToggleButton *editButton;
@property (nonatomic, retain) IBOutlet UITextField *addressField;
- (IBAction)onAddClick:(id) event;
- (IBAction)onEditClick:(id) event;
@end

View file

@ -0,0 +1,144 @@
/* ChatViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ChatViewController.h"
#import "PhoneMainView.h"
#import "ChatModel.h"
@implementation ChatViewController
@synthesize tableController;
@synthesize editButton;
@synthesize addressField;
#pragma mark - Lifecycle Functions
- (id)init {
return [super initWithNibName:@"ChatViewController" bundle:[NSBundle mainBundle]];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[tableController release];
[editButton release];
[addressField release];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[super viewDidLoad];
// Set selected+over background: IB lack !
[editButton setBackgroundImage:[UIImage imageNamed:@"chat_ok_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:editButton];
[tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
[tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textReceivedEvent:)
name:kLinphoneTextReceived
object:nil];
if([tableController isEditing])
[tableController setEditing:FALSE animated:FALSE];
[editButton setOff];
[tableController loadData];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneTextReceived
object:nil];
}
#pragma mark - Event Functions
- (void)textReceivedEvent:(NSNotification *)notif {
[tableController loadData];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"Chat"
content:@"ChatViewController"
stateBar:nil
stateBarEnabled:false
tabBar: @"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - Action Functions
-(void) startChatRoom {
//Push ChatRoom
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
if(controller != nil) {
[controller setRemoteAddress:[addressField text]];
}
addressField.text = @"";
}
- (IBAction)onAddClick:(id)event {
if ([[addressField text ]length] == 0) { // if no address is manually set, lauch address book
[ContactSelection setSelectionMode:ContactSelectionModeMessage];
[ContactSelection setAddAddress:nil];
[ContactSelection setSipFilter:TRUE];
[[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription] push:TRUE];
} else {
[self startChatRoom];
}
}
- (IBAction)onEditClick:(id)event {
[tableController setEditing:![tableController isEditing] animated:TRUE];
}
#pragma mark - UITextFieldDelegate Functions
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[addressField resignFirstResponder];
if ([[addressField text ]length]> 0)
[self startChatRoom];
return YES;
}
@end

View file

@ -1,257 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1280</int>
<string key="IBDocument.SystemVersion">11C74</string>
<string key="IBDocument.InterfaceBuilderVersion">1938</string>
<string key="IBDocument.AppKitVersion">1138.23</string>
<string key="IBDocument.HIToolboxVersion">567.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">933</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUITableViewCell</string>
<string>IBUIImageView</string>
<string>IBUILabel</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUITableViewCell" id="592306609">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="203820029">
<reference key="NSNextResponder" ref="592306609"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIImageView" id="565632536">
<reference key="NSNextResponder" ref="203820029"/>
<int key="NSvFlags">292</int>
<string key="NSFrameSize">{80, 80}</string>
<reference key="NSSuperview" ref="203820029"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="874623941"/>
<string key="NSReuseIdentifierKey">_NS:567</string>
<int key="IBUITag">1</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUILabel" id="874623941">
<reference key="NSNextResponder" ref="203820029"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{80, 0}, {212, 80}}</string>
<reference key="NSSuperview" ref="203820029"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="818419664"/>
<string key="NSReuseIdentifierKey">_NS:328</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<int key="IBUITag">2</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Texte de test</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">1</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">40</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">40</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIImageView" id="818419664">
<reference key="NSNextResponder" ref="203820029"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{292, 26}, {28, 28}}</string>
<reference key="NSSuperview" ref="203820029"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:567</string>
<int key="IBUITag">3</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 79}</string>
<reference key="NSSuperview" ref="592306609"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="565632536"/>
<string key="NSReuseIdentifierKey">_NS:395</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">4</int>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 80}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="203820029"/>
<string key="NSReuseIdentifierKey">_NS:384</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<reference key="IBUIContentView" ref="203820029"/>
<string key="IBUIReuseIdentifier">ConferenceDetailCellIdentifier</string>
<real value="80" key="IBUIRowHeight"/>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">conferenceDetailCell</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="592306609"/>
</object>
<int key="connectionID">7</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="592306609"/>
<array class="NSMutableArray" key="children">
<reference ref="565632536"/>
<reference ref="874623941"/>
<reference ref="818419664"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="565632536"/>
<reference key="parent" ref="592306609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">8</int>
<reference key="object" ref="818419664"/>
<reference key="parent" ref="592306609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="874623941"/>
<reference key="parent" ref="592306609"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">ConferenceCallDetailView</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="8.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">8</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">ConferenceCallDetailView</string>
<string key="superclassName">UIViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="addCall">UIButton</string>
<string key="back">UIButton</string>
<string key="conferenceDetailCell">UITableViewCell</string>
<string key="hangup">UIButton</string>
<string key="mute">UIButton</string>
<string key="speaker">UIButton</string>
<string key="table">UITableView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="addCall">
<string key="name">addCall</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="back">
<string key="name">back</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="conferenceDetailCell">
<string key="name">conferenceDetailCell</string>
<string key="candidateClassName">UITableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="hangup">
<string key="name">hangup</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="mute">
<string key="name">mute</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="speaker">
<string key="name">speaker</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="table">
<string key="name">table</string>
<string key="candidateClassName">UITableView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/ConferenceCallDetailView.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">933</string>
</data>
</archive>

View file

@ -1,479 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1280</int>
<string key="IBDocument.SystemVersion">11C74</string>
<string key="IBDocument.InterfaceBuilderVersion">1938</string>
<string key="IBDocument.AppKitVersion">1138.23</string>
<string key="IBDocument.HIToolboxVersion">567.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">933</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUIButton</string>
<string>IBUITableView</string>
<string>IBUIView</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
<object class="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUITableView" id="682450328">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{768, 872}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="492050748"/>
<string key="NSReuseIdentifierKey">_NS:418</string>
<object class="NSColor" key="IBUIBackgroundColor" id="270413770">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<bool key="IBUIAlwaysBounceVertical">YES</bool>
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
<bool key="IBUIAllowsSelection">NO</bool>
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
<float key="IBUIRowHeight">44</float>
<float key="IBUISectionHeaderHeight">22</float>
<float key="IBUISectionFooterHeight">22</float>
</object>
<object class="IBUIButton" id="492050748">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{224, 874}, {107, 66}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="548356310"/>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<object class="NSColor" key="IBUIHighlightedTitleColor" id="763261649">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor" id="102583944">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="NSCustomResource" key="IBUINormalBackgroundImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">effacer.png</string>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="758567310">
<string key="name">Helvetica-Bold</string>
<string key="family">Helvetica</string>
<int key="traits">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont" id="1000099959">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIButton" id="285534295">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{437, 873}, {107, 66}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<reference key="IBUIBackgroundColor" ref="270413770"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<reference key="IBUIHighlightedTitleColor" ref="763261649"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA</bytes>
</object>
<reference key="IBUINormalTitleShadowColor" ref="102583944"/>
<object class="NSCustomResource" key="IBUISelectedImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">HP_inverse.png</string>
</object>
<object class="NSCustomResource" key="IBUINormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">HP.png</string>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="322491891">
<int key="type">2</int>
<int key="size">2</int>
</object>
<object class="NSFont" key="IBUIFont" id="310685398">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">18</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIButton" id="548356310">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{224, 938}, {320, 66}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="378152807"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MSAwIDAuMDgyMzIwMjU5MDQgMC4xOAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<reference key="IBUIHighlightedTitleColor" ref="763261649"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
</object>
<reference key="IBUINormalTitleShadowColor" ref="102583944"/>
<object class="NSCustomResource" key="IBUINormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">stopcall-red.png</string>
</object>
<object class="NSCustomResource" key="IBUINormalBackgroundImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">clavier-01-106px.png</string>
</object>
<reference key="IBUIFontDescription" ref="758567310"/>
<reference key="IBUIFont" ref="1000099959"/>
</object>
<object class="IBUIButton" id="378152807">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{331, 873}, {106, 66}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="285534295"/>
<reference key="IBUIBackgroundColor" ref="270413770"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<reference key="IBUIHighlightedTitleColor" ref="763261649"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA</bytes>
</object>
<reference key="IBUINormalTitleShadowColor" ref="102583944"/>
<object class="NSCustomResource" key="IBUIDisabledImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">mic_active.png</string>
</object>
<object class="NSCustomResource" key="IBUISelectedImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">micro_inverse.png</string>
</object>
<object class="NSCustomResource" key="IBUINormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">micro.png</string>
</object>
<reference key="IBUIFontDescription" ref="322491891"/>
<reference key="IBUIFont" ref="310685398"/>
</object>
</array>
<string key="NSFrame">{{0, 20}, {768, 1004}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="682450328"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics">
<int key="IBUIStatusBarStyle">2</int>
</object>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">back</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="492050748"/>
</object>
<int key="connectionID">8</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">hangup</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="548356310"/>
</object>
<int key="connectionID">9</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">mute</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="378152807"/>
</object>
<int key="connectionID">10</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">speaker</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="285534295"/>
</object>
<int key="connectionID">11</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">table</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="682450328"/>
</object>
<int key="connectionID">12</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">13</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">dataSource</string>
<reference key="source" ref="682450328"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">14</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="682450328"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">15</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
<reference ref="682450328"/>
<reference ref="548356310"/>
<reference ref="378152807"/>
<reference ref="285534295"/>
<reference ref="492050748"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="492050748"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">Erase</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="285534295"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">speaker</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="682450328"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="548356310"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">end</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="378152807"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">mute</string>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">ConferenceCallDetailView</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.CustomClassName">UIEraseButton</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.CustomClassName">UISpeakerButton</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<real value="1" key="4.IBUIButtonInspectorSelectedStateConfigurationMetadataKey"/>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="6.CustomClassName">UIHangUpButton</string>
<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="7.CustomClassName">UIMuteButton</string>
<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<real value="2" key="7.IBUIButtonInspectorSelectedStateConfigurationMetadataKey"/>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">15</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">ConferenceCallDetailView</string>
<string key="superclassName">UIViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="addCall">UIButton</string>
<string key="back">UIButton</string>
<string key="conferenceDetailCell">UITableViewCell</string>
<string key="hangup">UIButton</string>
<string key="mute">UIButton</string>
<string key="speaker">UIButton</string>
<string key="table">UITableView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="addCall">
<string key="name">addCall</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="back">
<string key="name">back</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="conferenceDetailCell">
<string key="name">conferenceDetailCell</string>
<string key="candidateClassName">UITableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="hangup">
<string key="name">hangup</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="mute">
<string key="name">mute</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="speaker">
<string key="name">speaker</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="table">
<string key="name">table</string>
<string key="candidateClassName">UITableView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/ConferenceCallDetailView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UIEraseButton</string>
<string key="superclassName">UIButton</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UIEraseButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UIHangUpButton</string>
<string key="superclassName">UIButton</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UIHangUpButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UIMuteButton</string>
<string key="superclassName">UIToggleButton</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UIMuteButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UISpeakerButton</string>
<string key="superclassName">UIToggleButton</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UISpeakerButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UIToggleButton</string>
<string key="superclassName">UIButton</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UIToggleButton.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="HP.png">{107, 67}</string>
<string key="HP_inverse.png">{107, 67}</string>
<string key="clavier-01-106px.png">{106, 60}</string>
<string key="effacer.png">{66, 65}</string>
<string key="mic_active.png">{20, 20}</string>
<string key="micro.png">{107, 67}</string>
<string key="micro_inverse.png">{107, 67}</string>
<string key="stopcall-red.png">{62, 54}</string>
</dictionary>
<string key="IBCocoaTouchPluginVersion">933</string>
</data>
</archive>

View file

@ -1,165 +0,0 @@
/* ConferenceCallDetailView.m
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ConferenceCallDetailView.h"
#import "linphonecore.h"
#import "LinphoneManager.h"
#import "IncallViewController.h"
@implementation ConferenceCallDetailView
@synthesize mute;
@synthesize speaker;
@synthesize back;
@synthesize hangup;
@synthesize table;
@synthesize addCall;
@synthesize conferenceDetailCell;
NSTimer *callQualityRefresher;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (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.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[back addTarget:self action:@selector(backButtonPressed) forControlEvents:UIControlEventTouchUpInside];
table.rowHeight = 80;
[mute initWithOnImage:[UIImage imageNamed:@"micro_inverse.png"] offImage:[UIImage imageNamed:@"micro.png"] debugName:"MUTE button"];
[speaker initWithOnImage:[UIImage imageNamed:@"HP_inverse.png"] offImage:[UIImage imageNamed:@"HP.png"] debugName:"SPEAKER button"];
}
-(void) backButtonPressed {
[self dismissModalViewControllerAnimated:YES];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(void) viewWillAppear:(BOOL)animated {
[table reloadData];
[mute reset];
[speaker reset];
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
[super viewWillAppear:animated];
}
-(void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
callQualityRefresher = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(updateCallQuality)
userInfo:nil
repeats:YES];
}
-(void) viewDidDisappear:(BOOL)animated {
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
if (callQualityRefresher != nil) {
[callQualityRefresher invalidate];
callQualityRefresher=nil;
}
}
-(void) updateCallQuality {
[table reloadData];
[table setNeedsDisplay];
}
#pragma mark - UITableView delegates
-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row % 2)
cell.backgroundColor = [UIColor lightGrayColor];
else
cell.backgroundColor = [UIColor darkGrayColor];
}
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* identifier = @"ConferenceDetailCellIdentifier";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"ConferenceCallDetailCell" owner:self options:nil];
cell = conferenceDetailCell;
self.conferenceDetailCell = nil;
}
/* retrieve cell's fields using tags */
UIImageView* image = (UIImageView*) [cell viewWithTag:1];
UILabel* label = (UILabel*) [cell viewWithTag:2];
/* update cell content */
LinphoneCall* call = [IncallViewController retrieveCallAtIndex:indexPath.row inConference:YES];
[IncallViewController updateCellImageView:image Label:label DetailLabel:nil AndAccessoryView:nil withCall:call];
cell.accessoryType = UITableViewCellAccessoryNone;
if (cell.accessoryView == nil) {
UIView *containerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 28, 28)] autorelease];
cell.accessoryView = containerView;
}
else {
for (UIView *view in cell.accessoryView.subviews) {
[view removeFromSuperview];
}
}
UIImageView* callquality = (UIImageView*) [cell viewWithTag:3];
[IncallViewController updateIndicator:callquality withCallQuality:linphone_call_get_average_quality(call)];
tableView.rowHeight = 80;
return cell;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
LinphoneCore* lc = [LinphoneManager getLc];
int result = linphone_core_get_conference_size(lc) - (int)linphone_core_is_in_conference(lc);
return result;
}
@end

View file

@ -1,478 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1280</int>
<string key="IBDocument.SystemVersion">11C74</string>
<string key="IBDocument.InterfaceBuilderVersion">1938</string>
<string key="IBDocument.AppKitVersion">1138.23</string>
<string key="IBDocument.HIToolboxVersion">567.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">933</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUITableView</string>
<string>IBUIButton</string>
<string>IBUIView</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUITableView" id="202949628">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{320, 328}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="502975112"/>
<string key="NSReuseIdentifierKey">_NS:418</string>
<object class="NSColor" key="IBUIBackgroundColor" id="508694975">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIAlwaysBounceVertical">YES</bool>
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
<bool key="IBUIAllowsSelection">NO</bool>
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
<float key="IBUIRowHeight">44</float>
<float key="IBUISectionHeaderHeight">22</float>
<float key="IBUISectionFooterHeight">22</float>
</object>
<object class="IBUIButton" id="502975112">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{107, 328}, {106, 66}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<reference key="IBUIBackgroundColor" ref="508694975"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<object class="NSColor" key="IBUIHighlightedTitleColor" id="715364517">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor" id="129151944">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="NSCustomResource" key="IBUIDisabledImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">mic_active.png</string>
</object>
<object class="NSCustomResource" key="IBUISelectedImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">micro_inverse.png</string>
</object>
<object class="NSCustomResource" key="IBUINormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">micro.png</string>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="246923771">
<int key="type">2</int>
<int key="size">2</int>
</object>
<object class="NSFont" key="IBUIFont" id="213214630">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">18</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIButton" id="305687417">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{213, 328}, {107, 66}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="1019646602"/>
<reference key="IBUIBackgroundColor" ref="508694975"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<reference key="IBUIHighlightedTitleColor" ref="715364517"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA</bytes>
</object>
<reference key="IBUINormalTitleShadowColor" ref="129151944"/>
<object class="NSCustomResource" key="IBUISelectedImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">HP_inverse.png</string>
</object>
<object class="NSCustomResource" key="IBUINormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">HP.png</string>
</object>
<reference key="IBUIFontDescription" ref="246923771"/>
<reference key="IBUIFont" ref="213214630"/>
</object>
<object class="IBUIButton" id="874802963">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{0, 394}, {320, 66}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MSAwIDAuMDgyMzIwMjU5MDQgMC4xOAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<reference key="IBUIHighlightedTitleColor" ref="715364517"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
</object>
<reference key="IBUINormalTitleShadowColor" ref="129151944"/>
<object class="NSCustomResource" key="IBUINormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">stopcall-red.png</string>
</object>
<object class="NSCustomResource" key="IBUINormalBackgroundImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">clavier-01-106px.png</string>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="645103076">
<string key="name">Helvetica-Bold</string>
<string key="family">Helvetica</string>
<int key="traits">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont" id="1042027645">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIButton" id="1019646602">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{0, 328}, {107, 66}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="874802963"/>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<reference key="IBUIHighlightedTitleColor" ref="715364517"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<reference key="IBUINormalTitleShadowColor" ref="129151944"/>
<object class="NSCustomResource" key="IBUINormalBackgroundImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">effacer.png</string>
</object>
<reference key="IBUIFontDescription" ref="645103076"/>
<reference key="IBUIFont" ref="1042027645"/>
</object>
</array>
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="202949628"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">back</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="1019646602"/>
</object>
<int key="connectionID">16</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">hangup</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="874802963"/>
</object>
<int key="connectionID">17</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">mute</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="502975112"/>
</object>
<int key="connectionID">18</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">speaker</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="305687417"/>
</object>
<int key="connectionID">19</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">20</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">table</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="202949628"/>
</object>
<int key="connectionID">23</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">dataSource</string>
<reference key="source" ref="202949628"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">21</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="202949628"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">22</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
<reference ref="874802963"/>
<reference ref="305687417"/>
<reference ref="202949628"/>
<reference ref="502975112"/>
<reference ref="1019646602"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="202949628"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="502975112"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">mute</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">11</int>
<reference key="object" ref="874802963"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">end</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">12</int>
<reference key="object" ref="305687417"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">speaker</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">14</int>
<reference key="object" ref="1019646602"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">Erase</string>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">ConferenceCallDetailView</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="10.CustomClassName">UIMuteButton</string>
<string key="10.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<real value="2" key="10.IBUIButtonInspectorSelectedStateConfigurationMetadataKey"/>
<string key="11.CustomClassName">UIHangUpButton</string>
<string key="11.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="12.CustomClassName">UISpeakerButton</string>
<string key="12.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<real value="1" key="12.IBUIButtonInspectorSelectedStateConfigurationMetadataKey"/>
<string key="14.CustomClassName">UIEraseButton</string>
<string key="14.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">23</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">ConferenceCallDetailView</string>
<string key="superclassName">UIViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="addCall">UIButton</string>
<string key="back">UIButton</string>
<string key="conferenceDetailCell">UITableViewCell</string>
<string key="hangup">UIButton</string>
<string key="mute">UIButton</string>
<string key="speaker">UIButton</string>
<string key="table">UITableView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="addCall">
<string key="name">addCall</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="back">
<string key="name">back</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="conferenceDetailCell">
<string key="name">conferenceDetailCell</string>
<string key="candidateClassName">UITableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="hangup">
<string key="name">hangup</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="mute">
<string key="name">mute</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="speaker">
<string key="name">speaker</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="table">
<string key="name">table</string>
<string key="candidateClassName">UITableView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/ConferenceCallDetailView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UIEraseButton</string>
<string key="superclassName">UIButton</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UIEraseButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UIHangUpButton</string>
<string key="superclassName">UIButton</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UIHangUpButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UIMuteButton</string>
<string key="superclassName">UIToggleButton</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UIMuteButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UISpeakerButton</string>
<string key="superclassName">UIToggleButton</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UISpeakerButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UIToggleButton</string>
<string key="superclassName">UIButton</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UIToggleButton.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="HP.png">{107, 67}</string>
<string key="HP_inverse.png">{107, 67}</string>
<string key="clavier-01-106px.png">{106, 60}</string>
<string key="effacer.png">{66, 65}</string>
<string key="mic_active.png">{20, 20}</string>
<string key="micro.png">{107, 67}</string>
<string key="micro_inverse.png">{107, 67}</string>
<string key="stopcall-red.png">{62, 54}</string>
</dictionary>
<string key="IBCocoaTouchPluginVersion">933</string>
</data>
</archive>

View file

@ -17,20 +17,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "LogView.h"
#import "UICompositeViewController.h"
@interface ConsoleViewController : UIViewController <LogView> {
UITextView* logs;
UIView* logsView;
@interface ConsoleViewController : UIViewController<UICompositeViewDelegate, UIWebViewDelegate> {
}
-(void) doAction;
@property (nonatomic, retain) IBOutlet UITextView* logs;
@property (nonatomic, retain) IBOutlet UIView* logsView;
@property (nonatomic, retain) IBOutlet UIWebView* logsView;
@end

View file

@ -20,87 +20,134 @@
#import "ConsoleViewController.h"
@implementation ConsoleViewController
NSMutableString* MoreViewController_logs;
@synthesize logs;
@synthesize logsView;
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
#pragma mark - Lifecycle Functions
- (id)init {
return [super initWithNibName:@"ConsoleViewController" bundle:[NSBundle mainBundle]];
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem* clear = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemTrash
target:self
action:@selector(doAction)] autorelease];
[self.navigationItem setRightBarButtonItem:clear];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[logs setText:MoreViewController_logs];
}
- (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;
}
-(void) addLog:(NSString*) log {
@synchronized(self) {
if (!MoreViewController_logs) {
MoreViewController_logs = [[NSMutableString alloc] init];
}
[MoreViewController_logs appendString:log];
if (MoreViewController_logs.length > 50000) {
NSRange range = {0,log.length};
[MoreViewController_logs deleteCharactersInRange:range];
}
}
}
-(void) doAction{
@synchronized(self) {
NSMutableString* oldString = MoreViewController_logs;
MoreViewController_logs = [[NSMutableString alloc] init];
[oldString release];
[logs setText:@""];
}
}
- (void)dealloc {
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self];
[logsView release];
[super dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"ConsoleView"
content:@"ConsoleViewController"
stateBar:@"UIStateBar"
stateBarEnabled:true
tabBar:@"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[logsView loadHTMLString:@"<html><body><pre id=\"content\"></pre></body><html>" baseURL:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneLogsUpdate
object:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
[logsView setDelegate:self];
UIScrollView *scrollView = [ConsoleViewController defaultScrollView:logsView];
UIEdgeInsets inset = {0, 0, 10, 0};
[scrollView setContentInset:inset];
[scrollView setScrollIndicatorInsets:inset];
[scrollView setBounces:FALSE];
}
#pragma mark - UIWebViewDelegate Functions
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *logs = [[LinphoneManager instance].logs componentsJoinedByString:@"\n"];
[self addLog:logs scroll:TRUE];
// Set observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(logsUpdateEvent:)
name:kLinphoneLogsUpdate
object:nil];
}
#pragma mark - Event Functions
- (void)logsUpdateEvent:(NSNotification*)notif {
NSString *log = [notif.userInfo objectForKey: @"log"];
[self addLog:log scroll:FALSE];
}
#pragma mark -
+ (UIScrollView *)defaultScrollView:(UIWebView *)webView {
UIScrollView *scrollView = nil;
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 5.0) {
return webView.scrollView;
} else {
for (UIView *subview in [webView subviews]) {
if ([subview isKindOfClass:[UIScrollView class]]) {
scrollView = (UIScrollView *)subview;
}
}
}
return scrollView;
}
- (void)clear {
NSString *js = @"document.getElementById('content').innerHTML += ''";
[logsView stringByEvaluatingJavaScriptFromString:js];
}
- (void)addLog:(NSString*)log scroll:(BOOL)scroll {
log = [log stringByReplacingOccurrencesOfString:@"\r" withString:@""];
log = [log stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"];
log = [log stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
log = [log stringByReplacingOccurrencesOfString:@"&" withString:@"&amp;"];
log = [log stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"];
log = [log stringByReplacingOccurrencesOfString:@">" withString:@"&gt;"];
NSMutableString *js = [NSMutableString stringWithFormat:@"document.getElementById('content').innerHTML += \"%@\\n\";", log];
if(scroll) {
[js appendString:@"window.scrollTo(0, document.body.scrollHeight);"];
}
[logsView stringByEvaluatingJavaScriptFromString:js];
}
@end

View file

@ -13,8 +13,8 @@
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>IBProxyObject</string>
<string>IBUITextView</string>
<string>IBUIView</string>
<string>IBUIWebView</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -39,50 +39,25 @@
<int key="NSvFlags">292</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUITextView" id="249557632">
<object class="IBUIWebView" id="143119813">
<reference key="NSNextResponder" ref="679133499"/>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{320, 450}</string>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview" ref="679133499"/>
<reference key="NSWindow"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MSAxIDEAA</bytes>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor" id="951155758">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIClipsSubviews">YES</bool>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIShowsHorizontalScrollIndicator">NO</bool>
<bool key="IBUIDelaysContentTouches">NO</bool>
<bool key="IBUICanCancelContentTouches">NO</bool>
<bool key="IBUIBouncesZoom">NO</bool>
<bool key="IBUIEditable">NO</bool>
<string key="IBUIText"/>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<int key="IBUIAutocapitalizationType">2</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
</object>
</object>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<reference key="NSNextKeyView" ref="143119813"/>
<reference key="IBUIBackgroundColor" ref="951155758"/>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
@ -102,17 +77,9 @@
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">logsView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="679133499"/>
<reference key="destination" ref="143119813"/>
</object>
<int key="connectionID">13</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">logs</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="249557632"/>
</object>
<int key="connectionID">9</int>
<int key="connectionID">19</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
@ -142,15 +109,15 @@
<reference key="object" ref="679133499"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="249557632"/>
<reference ref="143119813"/>
</object>
<reference key="parent" ref="732835941"/>
<string key="objectName">logView</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="249557632"/>
<int key="objectID">18</int>
<reference key="object" ref="143119813"/>
<reference key="parent" ref="679133499"/>
<string key="objectName">logsView</string>
</object>
</object>
</object>
@ -162,8 +129,8 @@
<string>-1.IBPluginDependency</string>
<string>-2.CustomClassName</string>
<string>-2.IBPluginDependency</string>
<string>18.IBPluginDependency</string>
<string>4.IBPluginDependency</string>
<string>7.IBPluginDependency</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -187,7 +154,7 @@
<reference key="dict.values" ref="732835941"/>
</object>
<nil key="sourceID"/>
<int key="maxID">14</int>
<int key="maxID">19</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@ -196,35 +163,14 @@
<string key="className">ConsoleViewController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>logs</string>
<string>logsView</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UITextView</string>
<string>UIView</string>
</object>
<string key="NS.key.0">logsView</string>
<string key="NS.object.0">UIWebView</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>logs</string>
<string>logsView</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">logs</string>
<string key="candidateClassName">UITextView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">logsView</string>
<string key="candidateClassName">UIView</string>
</object>
<string key="NS.key.0">logsView</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">logsView</string>
<string key="candidateClassName">UIWebView</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@ -240,6 +186,10 @@
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<integer value="784" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1536" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
<integer value="3000" key="NS.object.0"/>

View file

@ -0,0 +1,25 @@
/* ContactDetailsDelegate.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
@protocol ContactDetailsDelegate <NSObject>
- (void)onRemove:(id)event;
- (void)onModification:(id)event;
@end

View file

@ -0,0 +1,39 @@
/* ContactDetailsLabelViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UICompositeViewController.h"
@protocol ContactDetailsLabelViewDelegate <NSObject>
- (void)changeContactDetailsLabel:(NSString*)label;
@end
@interface ContactDetailsLabelViewController : UIViewController<UITableViewDelegate, UITableViewDataSource, UICompositeViewDelegate> {
}
@property (nonatomic, copy) NSString *selectedData;
@property (nonatomic, retain) NSDictionary *dataList;
@property (nonatomic, retain) IBOutlet UITableView *tableView;
@property (nonatomic, retain) id<ContactDetailsLabelViewDelegate> delegate;
- (IBAction)onBackClick:(id)event;
@end

View file

@ -0,0 +1,150 @@
/* ContactDetailsLabelViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ContactDetailsLabelViewController.h"
#import "UACellBackgroundView.h"
#import "UILinphone.h"
#import "PhoneMainView.h"
@implementation ContactDetailsLabelViewController
@synthesize dataList;
@synthesize tableView;
@synthesize selectedData;
@synthesize delegate;
#pragma mark - Lifecycle Functions
- (void)dealloc {
[selectedData release];
[dataList release];
[tableView release];
[delegate release];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[super viewDidLoad];
[tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
[tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"ContactDetailsLabel"
content:@"ContactDetailsLabelViewController"
stateBar:nil
stateBarEnabled:false
tabBar:@"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark -
- (void)dismiss {
if([[[PhoneMainView instance] currentView] equal:[ContactDetailsLabelViewController compositeViewDescription]]) {
[[PhoneMainView instance] popCurrentView];
}
}
#pragma mark - Property Functions
- (void)setDataList:(NSDictionary *)adatalist {
if([dataList isEqualToDictionary:adatalist]) {
return;
}
[dataList release];
dataList = [adatalist retain];
[tableView reloadData];
}
- (void)setSelectedData:(NSString *)aselectedData {
if (selectedData != nil) {
[selectedData release];
}
selectedData = [[NSString alloc] initWithString:aselectedData];
[tableView reloadData];
}
#pragma mark - UITableViewDataSource Functions
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [dataList count];
}
- (UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"ContactDetailsLabelCell";
UITableViewCell *cell = [atableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kCellId] autorelease];
// Background View
UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView = selectedBackgroundView;
[selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR];
}
NSString* key = [[dataList allKeys] objectAtIndex:[indexPath row]];
[cell.textLabel setText:[dataList objectForKey:key]];
if ([key compare:selectedData]==0) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
} else {
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString* key = [[dataList allKeys] objectAtIndex:[indexPath row]];
[self setSelectedData:key];
[delegate changeContactDetailsLabel:key];
[self dismiss];
}
#pragma mark - Action Functions
- (IBAction)onBackClick:(id)event {
[self dismiss];
}
@end

View file

@ -0,0 +1,43 @@
/* ContactDetailsTableViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import "ContactDetailsDelegate.h"
#import "ContactDetailsLabelViewController.h"
#import "UIContactDetailsHeader.h"
#import "UIContactDetailsFooter.h"
@interface ContactDetailsTableViewController : UITableViewController<ContactDetailsLabelViewDelegate, UITextFieldDelegate> {
@private
NSMutableArray *dataCache;
NSMutableArray *labelArray;
NSIndexPath *editingIndexPath;
}
@property (nonatomic, assign) ABRecordRef contact;
@property (nonatomic, retain) IBOutlet id<ContactDetailsDelegate> contactDetailsDelegate;
@property (nonatomic, retain) IBOutlet UIContactDetailsHeader *headerController;
@property (nonatomic, retain) IBOutlet UIContactDetailsFooter *footerController;
- (BOOL)isValid;
- (void)addSipField:(NSString*)address;
@end

View file

@ -0,0 +1,724 @@
/* ContactDetailsTableViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ContactDetailsTableViewController.h"
#import "PhoneMainView.h"
#import "UIEditableTableViewCell.h"
#import "UACellBackgroundView.h"
#import "UILinphone.h"
#import "OrderedDictionary.h"
#import "FastAddressBook.h"
#import "Utils.h"
@interface Entry : NSObject
@property (assign) ABMultiValueIdentifier identifier;
@end
@implementation Entry
@synthesize identifier;
#pragma mark - Lifecycle Functions
- (id)initWithData:(ABMultiValueIdentifier)aidentifier {
self = [super init];
if (self != NULL) {
[self setIdentifier:aidentifier];
}
return self;
}
- (void)dealloc {
[super dealloc];
}
@end
@implementation ContactDetailsTableViewController
enum _ContactSections {
ContactSections_None = 0,
ContactSections_Number,
ContactSections_Sip,
ContactSections_MAX
};
static const int contactSections[ContactSections_MAX] = {ContactSections_None, ContactSections_Number, ContactSections_Sip};
@synthesize footerController;
@synthesize headerController;
@synthesize contactDetailsDelegate;
@synthesize contact;
#pragma mark - Lifecycle Functions
- (void)initContactDetailsTableViewController {
dataCache = [[NSMutableArray alloc] init];
labelArray = [[NSMutableArray alloc] initWithObjects:
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"],
[NSString stringWithString:(NSString*)kABPersonPhoneMobileLabel],
[NSString stringWithString:(NSString*)kABPersonPhoneIPhoneLabel],
[NSString stringWithString:(NSString*)kABPersonPhoneMainLabel], nil];
editingIndexPath = nil;
}
- (id)init {
self = [super init];
if (self) {
[self initContactDetailsTableViewController];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self initContactDetailsTableViewController];
}
return self;
}
- (void)dealloc {
if(contact != nil && ABRecordGetRecordID(contact) == kABRecordInvalidID) {
CFRelease(contact);
}
if(editingIndexPath != nil) {
[editingIndexPath release];
}
[labelArray release];
[dataCache release];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[super viewDidLoad];
[headerController view]; // Force view load
[footerController view]; // Force view load
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
#pragma mark -
- (BOOL)isValid {
return [headerController isValid];
}
- (void)updateModification {
[contactDetailsDelegate onModification:nil];
}
- (NSMutableArray*)getSectionData:(int)section {
if(contactSections[section] == ContactSections_Number) {
return [dataCache objectAtIndex:0];
} else if(contactSections[section] == ContactSections_Sip) {
return [dataCache objectAtIndex:1];
}
return nil;
}
+ (NSString*)localizeLabel:(NSString*)str {
CFStringRef lLocalizedLabel = ABAddressBookCopyLocalizedLabel((CFStringRef) str);
NSString * retStr = [NSString stringWithString:(NSString*) lLocalizedLabel];
CFRelease(lLocalizedLabel);
return retStr;
}
- (NSDictionary*)getLocalizedLabels {
OrderedDictionary *dict = [[OrderedDictionary alloc] initWithCapacity:[labelArray count]];
for(NSString *str in labelArray) {
[dict setObject:[ContactDetailsTableViewController localizeLabel:str] forKey:str];
}
return [dict autorelease];
}
- (void)loadData {
[dataCache removeAllObjects];
if(contact == NULL)
return;
[LinphoneLogger logc:LinphoneLoggerLog format:"Load data from contact %p", contact];
// Phone numbers
{
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
NSMutableArray *subArray = [NSMutableArray array];
if(lMap) {
for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) {
ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(lMap, i);
Entry *entry = [[Entry alloc] initWithData:identifier];
[subArray addObject: entry];
[entry release];
}
CFRelease(lMap);
}
[dataCache addObject:subArray];
}
// SIP (IM)
{
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
NSMutableArray *subArray = [NSMutableArray array];
if(lMap) {
for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) {
ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(lMap, i);
CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i);
BOOL add = false;
if(CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) {
if(CFStringCompare((CFStringRef)kContactSipField, CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey), kCFCompareCaseInsensitive) == 0) {
add = true;
}
} else {
add = true;
}
if(add) {
Entry *entry = [[Entry alloc] initWithData:identifier];
[subArray addObject: entry];
[entry release];
}
CFRelease(lDict);
}
CFRelease(lMap);
}
[dataCache addObject:subArray];
}
if(contactDetailsDelegate != nil) {
[contactDetailsDelegate onModification:nil];
}
[self.tableView reloadData];
}
- (void)addEntry:(UITableView*)tableview section:(NSInteger)section animated:(BOOL)animated {
[self addEntry:tableview section:section animated:animated value:@""];
}
- (void)addEntry:(UITableView*)tableview section:(NSInteger)section animated:(BOOL)animated value:(NSString *)value{
NSMutableArray *sectionArray = [self getSectionData:section];
NSUInteger count = [sectionArray count];
NSError* error = NULL;
bool added = TRUE;
if(contactSections[section] == ContactSections_Number) {
ABMultiValueIdentifier identifier;
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
ABMutableMultiValueRef lMap;
if(lcMap != NULL) {
lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
} else {
lMap = ABMultiValueCreateMutable(kABStringPropertyType);
}
CFStringRef label = (CFStringRef)[labelArray objectAtIndex:0];
if(!ABMultiValueAddValueAndLabel(lMap, [value copy], label, &identifier)) {
added = false;
}
if(added && ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, (CFErrorRef*)&error)) {
Entry *entry = [[Entry alloc] initWithData:identifier];
[sectionArray addObject:entry];
[entry release];
} else {
added = false;
[LinphoneLogger log:LinphoneLoggerLog format:@"Can't add entry: %@", [error localizedDescription]];
}
CFRelease(lMap);
} else if(contactSections[section] == ContactSections_Sip) {
ABMultiValueIdentifier identifier;
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
ABMutableMultiValueRef lMap;
if(lcMap != NULL) {
lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
} else {
lMap = ABMultiValueCreateMutable(kABDictionaryPropertyType);
}
CFStringRef keys[] = { kABPersonInstantMessageUsernameKey, kABPersonInstantMessageServiceKey };
CFTypeRef values[] = { [value copy], kContactSipField };
CFDictionaryRef lDict = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 1, NULL, NULL);
CFStringRef label = (CFStringRef)[labelArray objectAtIndex:0];
if(!ABMultiValueAddValueAndLabel(lMap, lDict, label, &identifier)) {
added = false;
}
CFRelease(lDict);
if(added && ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, (CFErrorRef*)&error)) {
Entry *entry = [[Entry alloc] initWithData:identifier];
[sectionArray addObject:entry];
[entry release];
} else {
added = false;
[LinphoneLogger log:LinphoneLoggerError format:@"Can't add entry: %@", [error localizedDescription]];
}
CFRelease(lMap);
}
if (added && animated) {
// Update accessory
if (count > 0) {
[tableview reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:count -1 inSection:section]] withRowAnimation:FALSE];
}
[tableview insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:count inSection:section]] withRowAnimation:UITableViewRowAnimationFade];
}
if(contactDetailsDelegate != nil) {
[contactDetailsDelegate onModification:nil];
}
}
- (void)removeEmptyEntry:(UITableView*)tableview section:(NSInteger)section animated:(BOOL)animated {
NSMutableArray *sectionDict = [self getSectionData:section];
int row = [sectionDict count] - 1;
if(row >= 0) {
Entry *entry = [sectionDict objectAtIndex:row];
if(contactSections[section] == ContactSections_Number) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef valueRef = ABMultiValueCopyValueAtIndex(lMap, index);
if(![(NSString*) valueRef length]) {
[self removeEntry:tableview path:[NSIndexPath indexPathForRow:row inSection:section] animated:animated];
}
CFRelease(valueRef);
CFRelease(lMap);
} else if(contactSections[section] == ContactSections_Sip) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, index);
CFStringRef valueRef = CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey);
if(![(NSString*) valueRef length]) {
[self removeEntry:tableview path:[NSIndexPath indexPathForRow:row inSection:section] animated:animated];
}
CFRelease(lDict);
CFRelease(lMap);
}
}
if(contactDetailsDelegate != nil) {
[contactDetailsDelegate onModification:nil];
}
}
- (void)removeEntry:(UITableView*)tableview path:(NSIndexPath*)indexPath animated:(BOOL)animated {
NSMutableArray *sectionArray = [self getSectionData:[indexPath section]];
Entry *entry = [sectionArray objectAtIndex:[indexPath row]];
if(contactSections[[indexPath section]] == ContactSections_Number) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueRemoveValueAndLabelAtIndex(lMap, index);
ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, nil);
CFRelease(lMap);
} else if(contactSections[[indexPath section]] == ContactSections_Sip) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueRemoveValueAndLabelAtIndex(lMap, index);
ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, nil);
CFRelease(lMap);
}
[sectionArray removeObjectAtIndex:[indexPath row]];
NSArray *tagInsertIndexPath = [NSArray arrayWithObject:indexPath];
if (animated) {
[tableview deleteRowsAtIndexPaths:tagInsertIndexPath withRowAnimation:UITableViewRowAnimationFade];
}
}
#pragma mark - Property Functions
- (void)setContact:(ABRecordRef)acontact {
if(contact != nil && ABRecordGetRecordID(contact) == kABRecordInvalidID) {
CFRelease(contact);
}
contact = acontact;
[self loadData];
[headerController setContact:contact];
}
- (void)addSipField:(NSString*)address {
int i = 0;
while(i < ContactSections_MAX && contactSections[i] != ContactSections_Sip) ++i;
[self addEntry:[self tableView] section:i animated:FALSE value:address];
}
#pragma mark - UITableViewDataSource Functions
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return ContactSections_MAX;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self getSectionData:section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"ContactDetailsCell";
UIEditableTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[[UIEditableTableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:kCellId] autorelease];
[cell.detailTextField setDelegate:self];
[cell.detailTextField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[cell.detailTextField setAutocorrectionType:UITextAutocorrectionTypeNo];
// Background View
UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView = selectedBackgroundView;
[selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR];
}
NSMutableArray *sectionDict = [self getSectionData:[indexPath section]];
Entry *entry = [sectionDict objectAtIndex:[indexPath row]];
NSString *value = @"";
NSString *label = @"";
if(contactSections[[indexPath section]] == ContactSections_Number) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index);
if(labelRef != NULL) {
label = [ContactDetailsTableViewController localizeLabel:(NSString*) labelRef];
CFRelease(labelRef);
}
CFStringRef valueRef = ABMultiValueCopyValueAtIndex(lMap, index);
if(valueRef != NULL) {
value = [ContactDetailsTableViewController localizeLabel:(NSString*) valueRef];
CFRelease(valueRef);
}
CFRelease(lMap);
} else if(contactSections[[indexPath section]] == ContactSections_Sip) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index);
if(labelRef != NULL) {
label = [ContactDetailsTableViewController localizeLabel:(NSString*) labelRef];
CFRelease(labelRef);
}
CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, index);
CFStringRef valueRef = CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey);
if(valueRef != NULL) {
value = [NSString stringWithString:(NSString*) valueRef];
}
CFRelease(lDict);
CFRelease(lMap);
}
[cell.textLabel setText:label];
[cell.detailTextLabel setText:value];
[cell.detailTextField setText:value];
if (contactSections[[indexPath section]] == ContactSections_Number) {
[cell.detailTextField setKeyboardType:UIKeyboardTypePhonePad];
[cell.detailTextField setPlaceholder:NSLocalizedString(@"Phone number", nil)];
} else if(contactSections[[indexPath section]] == ContactSections_Sip){
[cell.detailTextField setKeyboardType:UIKeyboardTypeASCIICapable];
[cell.detailTextField setPlaceholder:NSLocalizedString(@"SIP address", nil)];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSMutableArray *sectionDict = [self getSectionData:[indexPath section]];
Entry *entry = [sectionDict objectAtIndex:[indexPath row]];
if (![self isEditing]) {
NSString *dest;
if(contactSections[[indexPath section]] == ContactSections_Number) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef valueRef = ABMultiValueCopyValueAtIndex(lMap, index);
if(valueRef != NULL) {
dest = [ContactDetailsTableViewController localizeLabel:(NSString*) valueRef];
CFRelease(valueRef);
}
CFRelease(lMap);
} else if(contactSections[[indexPath section]] == ContactSections_Sip) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, index);
CFStringRef valueRef = CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey);
dest = [FastAddressBook normalizeSipURI:[NSString stringWithString:(NSString*) valueRef]];
CFRelease(lDict);
CFRelease(lMap);
}
if(dest != nil) {
NSString *displayName = [FastAddressBook getContactDisplayName:contact];
if([ContactSelection getSelectionMode] != ContactSelectionModeMessage) {
// Go to dialer view
DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
if(controller != nil) {
[controller call:dest displayName:displayName];
}
} else {
// Go to Chat room view
[[PhoneMainView instance] popToView:[ChatViewController compositeViewDescription]]; // Got to Chat and push ChatRoom
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
if(controller != nil) {
[controller setRemoteAddress:dest];
}
}
}
} else {
NSString *key = nil;
if(contactSections[[indexPath section]] == ContactSections_Number) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index);
if(labelRef != NULL) {
key = [NSString stringWithString:(NSString*) labelRef];
CFRelease(labelRef);
}
CFRelease(lMap);
} else if(contactSections[[indexPath section]] == ContactSections_Sip) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index);
if(labelRef != NULL) {
key = [NSString stringWithString:(NSString*) labelRef];
CFRelease(labelRef);
}
CFRelease(lMap);
}
if(key != nil) {
if(editingIndexPath != nil) {
[editingIndexPath release];
}
editingIndexPath = [indexPath copy];
ContactDetailsLabelViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsLabelViewController compositeViewDescription] push:TRUE], ContactDetailsLabelViewController);
if(controller != nil) {
[controller setDataList:[self getLocalizedLabels]];
[controller setSelectedData:key];
[controller setDelegate:self];
}
}
}
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
[LinphoneUtils findAndResignFirstResponder:[self tableView]];
if (editingStyle == UITableViewCellEditingStyleInsert) {
[tableView beginUpdates];
[self addEntry:tableView section:[indexPath section] animated:TRUE];
[tableView endUpdates];
} else if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
[self removeEntry:tableView path:indexPath animated:TRUE];
[tableView endUpdates];
}
}
#pragma mark - UITableViewDelegate Functions
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
// Resign keyboard
if(!editing) {
[LinphoneUtils findAndResignFirstResponder:[self tableView]];
}
[headerController setEditing:editing animated:animated];
[footerController setEditing:editing animated:animated];
if(animated) {
[self.tableView beginUpdates];
}
if(editing) {
for (int section = 0; section < [self numberOfSectionsInTableView:[self tableView]]; ++section) {
if(contactSections[section] == ContactSections_Number ||
contactSections[section] == ContactSections_Sip)
[self addEntry:self.tableView section:section animated:animated];
}
} else {
for (int section = 0; section < [self numberOfSectionsInTableView:[self tableView]]; ++section) {
if(contactSections[section] == ContactSections_Number ||
contactSections[section] == ContactSections_Sip)
[self removeEmptyEntry:self.tableView section:section animated:animated];
}
}
if(animated) {
[self.tableView endUpdates];
}
[super setEditing:editing animated:animated];
if(contactDetailsDelegate != nil) {
[contactDetailsDelegate onModification:nil];
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
int last_index = [[self getSectionData:[indexPath section]] count] - 1;
if (indexPath.row == last_index) {
return UITableViewCellEditingStyleInsert;
}
return UITableViewCellEditingStyleDelete;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if(section == ContactSections_None) {
return [headerController view];
} else {
return nil;
}
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
if(section == (ContactSections_MAX - 1)) {
if(ABRecordGetRecordID(contact) != kABRecordInvalidID) {
return [footerController view];
}
}
return nil;
}
- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if(contactSections[section] == ContactSections_Number) {
return NSLocalizedString(@"Phone numbers", nil);
} else if(contactSections[section] == ContactSections_Sip) {
return NSLocalizedString(@"SIP addresses", nil);
}
return nil;
}
- (NSString*)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
return @"";
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if(section == ContactSections_None) {
return [UIContactDetailsHeader height:[headerController isEditing]];
} else {
// Hide section if nothing in it
if([[self getSectionData:section] count] > 0)
return 22;
else
return 0.000001f; // Hack UITableView = 0
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
if(section == (ContactSections_MAX - 1)) {
if(ABRecordGetRecordID(contact) != kABRecordInvalidID) {
return [UIContactDetailsFooter height:[footerController isEditing]];
} else {
return 0.000001f; // Hack UITableView = 0
}
} else if(section == ContactSections_None) {
return 0.000001f; // Hack UITableView = 0
}
return 10.0f;
}
#pragma mark - ContactDetailsLabelDelegate Functions
- (void)changeContactDetailsLabel:(NSString *)value {
if(value != nil) {
NSMutableArray *sectionDict = [self getSectionData:[editingIndexPath section]];
Entry *entry = [sectionDict objectAtIndex:[editingIndexPath row]];
if(contactSections[[editingIndexPath section]] == ContactSections_Number) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceLabelAtIndex(lMap, (CFStringRef)(value), index);
ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, nil);
CFRelease(lMap);
} else if(contactSections[[editingIndexPath section]] == ContactSections_Sip) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceLabelAtIndex(lMap, (CFStringRef)(value), index);
ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, nil);
CFRelease(lMap);
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject: editingIndexPath] withRowAnimation:FALSE];
[self.tableView endUpdates];
}
[editingIndexPath release];
editingIndexPath = nil;
}
#pragma mark - UITextFieldDelegate Functions
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if(contactDetailsDelegate != nil) {
[self performSelector:@selector(updateModification) withObject:nil afterDelay:0];
}
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
UIView *view = [textField superview];
// Find TableViewCell
if(view != nil && ![view isKindOfClass:[UIEditableTableViewCell class]]) view = [view superview];
if(view != nil) {
UIEditableTableViewCell *cell = (UIEditableTableViewCell*)view;
NSIndexPath *path = [self.tableView indexPathForCell:cell];
NSMutableArray *sectionDict = [self getSectionData:[path section]];
Entry *entry = [sectionDict objectAtIndex:[path row]];
NSString *value = [textField text];
if(contactSections[[path section]] == ContactSections_Number) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceValueAtIndex(lMap, (CFStringRef)value, index);
ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, nil);
CFRelease(lMap);
} else if(contactSections[[path section]] == ContactSections_Sip) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef keys[] = { kABPersonInstantMessageUsernameKey, kABPersonInstantMessageServiceKey};
CFTypeRef values[] = { [value copy], kContactSipField };
CFDictionaryRef lDict = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, NULL, NULL);
ABMultiValueReplaceValueAtIndex(lMap, lDict, index);
CFRelease(lDict);
ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, nil);
CFRelease(lMap);
}
[cell.detailTextLabel setText:value];
} else {
[LinphoneLogger logc:LinphoneLoggerError format:"Not valid UIEditableTableViewCell"];
}
if(contactDetailsDelegate != nil) {
[self performSelector:@selector(updateModification) withObject:nil afterDelay:0];
}
return TRUE;
}
@end

View file

@ -0,0 +1,47 @@
/* ContactDetailsViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import "UICompositeViewController.h"
#import "UIToggleButton.h"
#import "ContactDetailsTableViewController.h"
@interface ContactDetailsViewController : UIViewController<UICompositeViewDelegate, ContactDetailsDelegate> {
ABAddressBookRef addressBook;
BOOL inhibUpdate;
}
@property (nonatomic, assign) ABRecordRef contact;
@property (nonatomic, retain) IBOutlet ContactDetailsTableViewController *tableController;
@property (nonatomic, retain) IBOutlet UIToggleButton *editButton;
@property (nonatomic, retain) IBOutlet UIButton *backButton;
@property (nonatomic, retain) IBOutlet UIButton *cancelButton;
- (IBAction)onBackClick:(id)event;
- (IBAction)onCancelClick:(id)event;
- (IBAction)onEditClick:(id)event;
- (void)newContact;
- (void)newContact:(NSString*)address;
- (void)editContact:(ABRecordRef)contact;
- (void)editContact:(ABRecordRef)contact address:(NSString*)address;
@end

View file

@ -0,0 +1,333 @@
/* ContactDetailsViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ContactDetailsViewController.h"
#import "PhoneMainView.h"
@implementation ContactDetailsViewController
@synthesize tableController;
@synthesize contact;
@synthesize editButton;
@synthesize backButton;
@synthesize cancelButton;
static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context);
#pragma mark - Lifecycle Functions
- (id)init {
self = [super initWithNibName:@"ContactDetailsViewController" bundle:[NSBundle mainBundle]];
if(self != nil) {
inhibUpdate = FALSE;
addressBook = ABAddressBookCreate();
ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, self);
}
return self;
}
- (void)dealloc {
ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self);
CFRelease(addressBook);
[tableController release];
[editButton release];
[backButton release];
[cancelButton release];
[super dealloc];
}
#pragma mark -
- (void)resetData {
[self disableEdit:FALSE];
if(contact == NULL) {
ABAddressBookRevert(addressBook);
return;
}
[LinphoneLogger logc:LinphoneLoggerLog format:"Reset data to contact %p", contact];
ABRecordID recordID = ABRecordGetRecordID(contact);
ABAddressBookRevert(addressBook);
contact = ABAddressBookGetPersonWithRecordID(addressBook, recordID);
if(contact == NULL) {
[[PhoneMainView instance] popCurrentView];
return;
}
[tableController setContact:contact];
}
static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
ContactDetailsViewController* controller = (ContactDetailsViewController*)context;
if(!controller->inhibUpdate && ![[controller tableController] isEditing]) {
[controller resetData];
}
}
- (void)removeContact {
if(contact == NULL) {
[[PhoneMainView instance] popCurrentView];
return;
}
// Remove contact from book
if(ABRecordGetRecordID(contact) != kABRecordInvalidID) {
NSError* error = NULL;
ABAddressBookRemoveRecord(addressBook, contact, (CFErrorRef*)&error);
if (error != NULL) {
[LinphoneLogger log:LinphoneLoggerError format:@"Remove contact %p: Fail(%@)", contact, [error localizedDescription]];
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"Remove contact %p: Success!", contact];
}
contact = NULL;
// Save address book
error = NULL;
inhibUpdate = TRUE;
ABAddressBookSave(addressBook, (CFErrorRef*)&error);
inhibUpdate = FALSE;
if (error != NULL) {
[LinphoneLogger log:LinphoneLoggerError format:@"Save AddressBook: Fail(%@)", [error localizedDescription]];
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"Save AddressBook: Success!"];
}
}
}
- (void)saveData {
if(contact == NULL) {
[[PhoneMainView instance] popCurrentView];
return;
}
// Add contact to book
NSError* error = NULL;
if(ABRecordGetRecordID(contact) == kABRecordInvalidID) {
ABAddressBookAddRecord(addressBook, contact, (CFErrorRef*)&error);
if (error != NULL) {
[LinphoneLogger log:LinphoneLoggerError format:@"Add contact %p: Fail(%@)", contact, [error localizedDescription]];
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"Add contact %p: Success!", contact];
}
}
// Save address book
error = NULL;
inhibUpdate = TRUE;
ABAddressBookSave(addressBook, (CFErrorRef*)&error);
inhibUpdate = FALSE;
if (error != NULL) {
[LinphoneLogger log:LinphoneLoggerError format:@"Save AddressBook: Fail(%@)", [error localizedDescription]];
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"Save AddressBook: Success!"];
}
}
- (void)newContact {
[LinphoneLogger logc:LinphoneLoggerLog format:"New contact"];
contact = NULL;
[self resetData];
contact = ABPersonCreate();
[tableController setContact:contact];
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
}
- (void)newContact:(NSString*)address {
[LinphoneLogger logc:LinphoneLoggerLog format:"New contact"];
contact = NULL;
[self resetData];
contact = ABPersonCreate();
[tableController setContact:contact];
[tableController addSipField:address];
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
}
- (void)editContact:(ABRecordRef)acontact {
[LinphoneLogger logc:LinphoneLoggerLog format:"Edit contact %p", acontact];
contact = NULL;
[self resetData];
contact = ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact));
[tableController setContact:contact];
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
}
- (void)editContact:(ABRecordRef)acontact address:(NSString*)address {
[LinphoneLogger logc:LinphoneLoggerLog format:"Edit contact %p", acontact];
contact = NULL;
[self resetData];
contact = ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact));
[tableController setContact:contact];
[tableController addSipField:address];
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
}
#pragma mark - Property Functions
- (void)setContact:(ABRecordRef)acontact {
[LinphoneLogger logc:LinphoneLoggerLog format:"Set contact %p", acontact];
contact = NULL;
[self resetData];
contact = ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact));
[tableController setContact:contact];
}
#pragma mark - ViewController Functions
- (void)viewDidLoad{
[super viewDidLoad];
// Set selected+over background: IB lack !
[editButton setBackgroundImage:[UIImage imageNamed:@"contact_ok_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
// Set selected+disabled background: IB lack !
[editButton setBackgroundImage:[UIImage imageNamed:@"contact_ok_disabled.png"]
forState:(UIControlStateDisabled | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:editButton];
[tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
[tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewWillDisappear:animated];
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if([ContactSelection getSelectionMode] == ContactSelectionModeEdit ||
[ContactSelection getSelectionMode] == ContactSelectionModeNone) {
[editButton setHidden:FALSE];
} else {
[editButton setHidden:TRUE];
}
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewWillAppear:animated];
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewDidAppear:animated];
}
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewDidDisappear:animated];
}
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"ContactDetails"
content:@"ContactDetailsViewController"
stateBar:nil
stateBarEnabled:false
tabBar:@"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark -
- (void)enableEdit:(BOOL)animated {
if(![tableController isEditing]) {
[tableController setEditing:TRUE animated:animated];
}
[editButton setOn];
[cancelButton setHidden:FALSE];
[backButton setHidden:TRUE];
}
- (void)disableEdit:(BOOL)animated {
if([tableController isEditing]) {
[tableController setEditing:FALSE animated:animated];
}
[editButton setOff];
[cancelButton setHidden:TRUE];
[backButton setHidden:FALSE];
}
#pragma mark - Action Functions
- (IBAction)onCancelClick:(id)event {
[self disableEdit:TRUE];
[self resetData];
}
- (IBAction)onBackClick:(id)event {
if([ContactSelection getSelectionMode] == ContactSelectionModeEdit) {
[ContactSelection setSelectionMode:ContactSelectionModeNone];
}
[[PhoneMainView instance] popCurrentView];
}
- (IBAction)onEditClick:(id)event {
if([tableController isEditing]) {
if([tableController isValid]) {
[self disableEdit:TRUE];
[self saveData];
}
} else {
[self enableEdit:TRUE];
}
}
- (void)onRemove:(id)event {
[self disableEdit:FALSE];
[self removeContact];
[[PhoneMainView instance] popCurrentView];
}
- (void)onModification:(id)event {
if(![tableController isEditing] || [tableController isValid]) {
[editButton setEnabled:TRUE];
} else {
[editButton setEnabled:FALSE];
}
}
@end

View file

@ -1,53 +0,0 @@
/* ContactPickerDelegate.m
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ContactPickerDelegate.h"
#import "LinphoneManager.h"
@implementation ContactPickerDelegate
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
return true;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier {
CFTypeRef multiValue = ABRecordCopyValue(person, property);
CFIndex valueIdx = ABMultiValueGetIndexForIdentifier(multiValue,identifier);
NSString *phoneNumber = (NSString *)ABMultiValueCopyValueAtIndex(multiValue, valueIdx);
[[LinphoneManager instance].callDelegate displayDialerFromUI:nil
forUser:phoneNumber
withDisplayName:[(NSString*)ABRecordCopyCompositeName(person) autorelease]];
[phoneNumber release];
CFRelease(multiValue);
return false;
}
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
[[LinphoneManager instance].callDelegate displayDialerFromUI:nil
forUser:nil
withDisplayName:@""];
}
@end

View file

@ -1,6 +1,6 @@
/* GenericTabViewController.h
/* ContactsTableViewController.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -18,14 +18,18 @@
*/
#import <UIKit/UIKit.h>
#include "linphonecore.h"
#import "PhoneViewController.h"
#import "linphoneAppDelegate.h"
#import <AddressBook/AddressBook.h>
@interface GenericTabViewController : UITableViewController {
LinphoneCore* myLinphoneCore;
IBOutlet UIView* header;
#import "OrderedDictionary.h"
@interface ContactsTableViewController : UITableViewController {
@private
OrderedDictionary* addressBookMap;
NSMutableDictionary* avatarMap;
ABAddressBookRef addressBook;
}
@property (nonatomic, retain) IBOutlet UIView* header;
@end
- (void)loadData;
@end

View file

@ -0,0 +1,246 @@
/* ContactsTableViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ContactsTableViewController.h"
#import "UIContactCell.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import "UACellBackgroundView.h"
#import "UILinphone.h"
#import "Utils.h"
@implementation ContactsTableViewController
static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context);
#pragma mark - Lifecycle Functions
- (void)initContactsTableViewController {
addressBookMap = [[OrderedDictionary alloc] init];
avatarMap = [[NSMutableDictionary alloc] init];
addressBook = ABAddressBookCreate();
ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, self);
}
- (id)init {
self = [super init];
if (self) {
[self initContactsTableViewController];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self initContactsTableViewController];
}
return self;
}
- (void)dealloc {
ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self);
CFRelease(addressBook);
[addressBookMap release];
[avatarMap release];
[super dealloc];
}
#pragma mark -
- (void)loadData {
[LinphoneLogger logc:LinphoneLoggerLog format:"Load contact list"];
@synchronized (addressBookMap) {
// Reset Address book
[addressBookMap removeAllObjects];
NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
for (id lPerson in lContacts) {
BOOL add = true;
if([ContactSelection getSipFilter]) {
add = false;
ABMultiValueRef lMap = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonInstantMessageProperty);
for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) {
CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i);
if(CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) {
CFStringRef serviceKey = CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey);
if(CFStringCompare((CFStringRef)@"SIP", serviceKey, kCFCompareCaseInsensitive) == 0) {
add = true;
}
} else {
NSString* usernameKey = CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey);
if([usernameKey hasPrefix:@"sip:"]) {
add = true;
}
}
CFRelease(lDict);
}
}
if(add) {
CFStringRef lFirstName = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonFirstNameProperty);
CFStringRef lLocalizedFirstName = (lFirstName != nil)? ABAddressBookCopyLocalizedLabel(lFirstName): nil;
CFStringRef lLastName = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonLastNameProperty);
CFStringRef lLocalizedLastName = (lLastName != nil)? ABAddressBookCopyLocalizedLabel(lLastName): nil;
CFStringRef lOrganization = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonOrganizationProperty);
CFStringRef lLocalizedlOrganization = (lOrganization != nil)? ABAddressBookCopyLocalizedLabel(lOrganization): nil;
NSString *name = nil;
if(lLocalizedFirstName != nil && lLocalizedLastName != nil) {
name=[NSString stringWithFormat:@"%@%@", [(NSString *)lLocalizedFirstName retain], [(NSString *)lLocalizedLastName retain]];
} else if(lLocalizedLastName != nil) {
name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedLastName retain]];
} else if(lLocalizedFirstName != nil) {
name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedFirstName retain]];
} else if(lLocalizedlOrganization != nil) {
name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedlOrganization retain]];
}
if(name != nil && [name length] > 0) {
// Put in correct subDic
NSString *firstChar = [[name substringToIndex:1] uppercaseString];
if([firstChar characterAtIndex:0] < 'A' || [firstChar characterAtIndex:0] > 'Z') {
firstChar = @"#";
}
OrderedDictionary *subDic =[addressBookMap objectForKey: firstChar];
if(subDic == nil) {
subDic = [[[OrderedDictionary alloc] init] autorelease];
[addressBookMap insertObject:subDic forKey:firstChar selector:@selector(caseInsensitiveCompare:)];
}
[subDic insertObject:lPerson forKey:name selector:@selector(caseInsensitiveCompare:)];
}
if(lLocalizedlOrganization != nil)
CFRelease(lLocalizedlOrganization);
if(lOrganization != nil)
CFRelease(lOrganization);
if(lLocalizedLastName != nil)
CFRelease(lLocalizedLastName);
if(lLastName != nil)
CFRelease(lLastName);
if(lLocalizedFirstName != nil)
CFRelease(lLocalizedFirstName);
if(lFirstName != nil)
CFRelease(lFirstName);
}
}
if (lContacts) CFRelease(lContacts);
}
[self.tableView reloadData];
}
static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
ContactsTableViewController* controller = (ContactsTableViewController*)context;
ABAddressBookRevert(addressBook);
[controller->avatarMap removeAllObjects];
[controller loadData];
}
#pragma mark - ViewController Functions
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
#pragma mark - UITableViewDataSource Functions
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [addressBookMap allKeys];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [addressBookMap count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [(OrderedDictionary *)[addressBookMap objectForKey: [addressBookMap keyAtIndex: section]] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"UIContactCell";
UIContactCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[[UIContactCell alloc] initWithIdentifier:kCellId] autorelease];
// Background View
UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView = selectedBackgroundView;
[selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR];
}
OrderedDictionary *subDic = [addressBookMap objectForKey: [addressBookMap keyAtIndex: [indexPath section]]];
NSString *key = [[subDic allKeys] objectAtIndex:[indexPath row]];
ABRecordRef contact = [subDic objectForKey:key];
// Cached avatar
UIImage *image = nil;
id data = [avatarMap objectForKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]];
if(data == nil) {
image = [FastAddressBook getContactImage:contact thumbnail:true];
if(image != nil) {
[avatarMap setObject:image forKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]];
} else {
[avatarMap setObject:[NSNull null] forKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]];
}
} else if(data != [NSNull null]) {
image = data;
}
if(image == nil) {
image = [UIImage imageNamed:@"avatar_unknown_small.png"];
}
[[cell avatarImage] setImage:image];
[cell setContact: contact];
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [addressBookMap keyAtIndex: section];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
OrderedDictionary *subDic = [addressBookMap objectForKey: [addressBookMap keyAtIndex: [indexPath section]]];
ABRecordRef lPerson = [subDic objectForKey: [subDic keyAtIndex:[indexPath row]]];
// Go to Contact details view
ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController);
if(controller != nil) {
if([ContactSelection getSelectionMode] != ContactSelectionModeEdit) {
[controller setContact:lPerson];
} else {
[controller editContact:lPerson address:[ContactSelection getAddAddress]];
}
}
}
#pragma mark - UITableViewDelegate Functions
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
// Detemine if it's in editing mode
if (self.editing) {
return UITableViewCellEditingStyleDelete;
}
return UITableViewCellEditingStyleNone;
}
@end

View file

@ -0,0 +1,59 @@
/* ContactsViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UICompositeViewController.h"
#import "ContactsTableViewController.h"
typedef enum _ContactSelectionMode {
ContactSelectionModeNone,
ContactSelectionModeEdit,
ContactSelectionModePhone,
ContactSelectionModeMessage
} ContactSelectionMode;
@interface ContactSelection : NSObject {
}
+ (void)setSelectionMode:(ContactSelectionMode)selectionMode;
+ (ContactSelectionMode)getSelectionMode;
+ (void)setAddAddress:(NSString*)address;
+ (NSString*)getAddAddress;
+ (void)setSipFilter:(BOOL)enable;
+ (BOOL)getSipFilter;
@end
@interface ContactsViewController : UIViewController<UICompositeViewDelegate> {
}
@property (nonatomic, retain) IBOutlet ContactsTableViewController* tableController;
@property (nonatomic, retain) IBOutlet UITableView *tableView;
@property (nonatomic, retain) IBOutlet UIButton* allButton;
@property (nonatomic, retain) IBOutlet UIButton* linphoneButton;
@property (nonatomic, retain) IBOutlet UIButton *backButton;
@property (nonatomic, retain) IBOutlet UIButton *addButton;
- (IBAction)onAllClick:(id)event;
- (IBAction)onLinphoneClick:(id)event;
- (IBAction)onAddContactClick:(id)event;
- (IBAction)onBackClick:(id)event;
@end

View file

@ -0,0 +1,256 @@
/* ContactsViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ContactsViewController.h"
#import "PhoneMainView.h"
#import "Utils.h"
#import <AddressBook/ABPerson.h>
@implementation ContactSelection
static ContactSelectionMode sSelectionMode = ContactSelectionModeNone;
static NSString* sAddAddress = nil;
static BOOL sSipFilter = FALSE;
+ (void)setSelectionMode:(ContactSelectionMode)selectionMode {
sSelectionMode = selectionMode;
}
+ (ContactSelectionMode)getSelectionMode {
return sSelectionMode;
}
+ (void)setAddAddress:(NSString*)address {
if(sAddAddress != nil) {
[sAddAddress release];
sAddAddress= nil;
}
if(address != nil) {
sAddAddress = [address retain];
}
}
+ (NSString*)getAddAddress {
return sAddAddress;
}
+ (void)setSipFilter:(BOOL)enable {
sSipFilter = enable;
}
+ (BOOL)getSipFilter {
return sSipFilter;
}
@end
@implementation ContactsViewController
@synthesize tableController;
@synthesize tableView;
@synthesize allButton;
@synthesize linphoneButton;
@synthesize backButton;
@synthesize addButton;
typedef enum _HistoryView {
History_All,
History_Linphone,
History_MAX
} HistoryView;
#pragma mark - Lifecycle Functions
- (id)init {
return [super initWithNibName:@"ContactsViewController" bundle:[NSBundle mainBundle]];
}
- (void)dealloc {
[tableController release];
[tableView release];
[allButton release];
[linphoneButton release];
[backButton release];
[addButton release];
[super dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"Contacts"
content:@"ContactsViewController"
stateBar:nil
stateBarEnabled:false
tabBar:@"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - ViewController Functions
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewWillDisappear:animated];
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewWillAppear:animated];
}
[self update];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewDidAppear:animated];
}
if(![FastAddressBook isAuthorized]) {
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Address book",nil)
message:NSLocalizedString(@"You must authorize the application to have access to address book.\n"
"Toggle the application in Settings > Privacy > Contacts",nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil];
[error show];
[error release];
[[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]];
}
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewDidDisappear:animated];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[self changeView:History_All];
// Set selected+over background: IB lack !
[linphoneButton setBackgroundImage:[UIImage imageNamed:@"contacts_linphone_selected.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[linphoneButton setTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]
forState:UIControlStateNormal];
[LinphoneUtils buttonFixStates:linphoneButton];
// Set selected+over background: IB lack !
[allButton setBackgroundImage:[UIImage imageNamed:@"contacts_all_selected.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:allButton];
[tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
[tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4
}
#pragma mark -
- (void)changeView:(HistoryView)view {
if(view == History_All) {
[ContactSelection setSipFilter:FALSE];
[tableController loadData];
allButton.selected = TRUE;
} else {
allButton.selected = FALSE;
}
if(view == History_Linphone) {
[ContactSelection setSipFilter:TRUE];
[tableController loadData];
linphoneButton.selected = TRUE;
} else {
linphoneButton.selected = FALSE;
}
}
- (void)update {
switch ([ContactSelection getSelectionMode]) {
case ContactSelectionModePhone:
case ContactSelectionModeMessage:
[addButton setHidden:TRUE];
[backButton setHidden:FALSE];
break;
default:
[addButton setHidden:FALSE];
[backButton setHidden:TRUE];
break;
}
if([ContactSelection getSipFilter]) {
allButton.selected = FALSE;
linphoneButton.selected = TRUE;
} else {
allButton.selected = TRUE;
linphoneButton.selected = FALSE;
}
[tableController loadData];
}
#pragma mark - Action Functions
- (IBAction)onAllClick:(id)event {
[self changeView: History_All];
}
- (IBAction)onLinphoneClick:(id)event {
[self changeView: History_Linphone];
}
- (IBAction)onAddContactClick:(id)event {
// Go to Contact details view
ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController);
if(controller != nil) {
if([ContactSelection getAddAddress] == nil) {
[controller newContact];
} else {
[controller newContact:[ContactSelection getAddAddress]];
}
}
}
- (IBAction)onBackClick:(id)event {
[[PhoneMainView instance] popCurrentView];
}
@end

13
Classes/Data/ChatData.h Normal file
View file

@ -0,0 +1,13 @@
//
// ChatData.h
// linphone
//
// Created by Diorcet Yann on 05/07/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ChatData : NSObject
@end

13
Classes/Data/ChatData.m Normal file
View file

@ -0,0 +1,13 @@
//
// ChatData.m
// linphone
//
// Created by Diorcet Yann on 05/07/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "ChatData.h"
@implementation ChatData
@end

View file

@ -0,0 +1,67 @@
/* DialerViewController.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UICompositeViewController.h"
#import "UIEraseButton.h"
#import "UICamSwitch.h"
#import "UICallButton.h"
#import "UITransferButton.h"
#import "UIDigitButton.h"
@interface DialerViewController : UIViewController <UITextFieldDelegate, UICompositeViewDelegate> {
}
- (void)setAddress:(NSString*)address;
- (void)call:(NSString*)address displayName:(NSString *)displayName;
- (void)call:(NSString*)address;
@property (nonatomic, assign) BOOL transferMode;
@property (nonatomic, retain) IBOutlet UITextField* addressField;
@property (nonatomic, retain) IBOutlet UIButton* addContactButton;
@property (nonatomic, retain) IBOutlet UICallButton* callButton;
@property (nonatomic, retain) IBOutlet UICallButton* addCallButton;
@property (nonatomic, retain) IBOutlet UITransferButton* transferButton;
@property (nonatomic, retain) IBOutlet UIButton* backButton;
@property (nonatomic, retain) IBOutlet UIEraseButton* eraseButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* oneButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* twoButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* threeButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* fourButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* fiveButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* sixButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* sevenButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* eightButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* nineButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* starButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* zeroButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* sharpButton;
@property (nonatomic, retain) IBOutlet UIView* backgroundView;
@property (nonatomic, retain) IBOutlet UIView* videoPreview;
@property (nonatomic, retain) IBOutlet UICamSwitch* videoCameraSwitch;
- (IBAction)onAddContactClick: (id) event;
- (IBAction)onBackClick: (id) event;
- (IBAction)onAddressChange: (id)sender;
@end

View file

@ -0,0 +1,347 @@
/* DialerViewController.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <AVFoundation/AVAudioSession.h>
#import <AudioToolbox/AudioToolbox.h>
#import "DialerViewController.h"
#import "IncallViewController.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import "Utils.h"
#include "linphonecore.h"
@implementation DialerViewController
@synthesize transferMode;
@synthesize addressField;
@synthesize addContactButton;
@synthesize backButton;
@synthesize addCallButton;
@synthesize transferButton;
@synthesize callButton;
@synthesize eraseButton;
@synthesize oneButton;
@synthesize twoButton;
@synthesize threeButton;
@synthesize fourButton;
@synthesize fiveButton;
@synthesize sixButton;
@synthesize sevenButton;
@synthesize eightButton;
@synthesize nineButton;
@synthesize starButton;
@synthesize zeroButton;
@synthesize sharpButton;
@synthesize backgroundView;
@synthesize videoPreview;
@synthesize videoCameraSwitch;
#pragma mark - Lifecycle Functions
- (id)init {
self = [super initWithNibName:@"DialerViewController" bundle:[NSBundle mainBundle]];
if(self) {
self->transferMode = FALSE;
}
return self;
}
- (void)dealloc {
[addressField release];
[addContactButton release];
[backButton release];
[eraseButton release];
[callButton release];
[addCallButton release];
[transferButton release];
[oneButton release];
[twoButton release];
[threeButton release];
[fourButton release];
[fiveButton release];
[sixButton release];
[sevenButton release];
[eightButton release];
[nineButton release];
[starButton release];
[zeroButton release];
[sharpButton release];
[videoPreview release];
[videoCameraSwitch release];
// Remove all observers
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"Dialer"
content:@"DialerViewController"
stateBar:@"UIStateBar"
stateBarEnabled:true
tabBar:@"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Set observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(coreUpdateEvent:)
name:kLinphoneCoreUpdate
object:nil];
// Update on show
if([LinphoneManager isLcReady]) {
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* call = linphone_core_get_current_call(lc);
LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0;
[self callUpdate:call state:state];
if([LinphoneManager runningOnIpad]) {
if(linphone_core_video_enabled(lc) && linphone_core_video_preview_enabled(lc)) {
linphone_core_set_native_preview_window_id(lc, (unsigned long)videoPreview);
[backgroundView setHidden:FALSE];
[videoCameraSwitch setHidden:FALSE];
} else {
linphone_core_set_native_preview_window_id(lc, (unsigned long)NULL);
[backgroundView setHidden:TRUE];
[videoCameraSwitch setHidden:TRUE];
}
}
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCallUpdate
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCoreUpdate
object:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
[zeroButton setDigit:'0'];
[oneButton setDigit:'1'];
[twoButton setDigit:'2'];
[threeButton setDigit:'3'];
[fourButton setDigit:'4'];
[fiveButton setDigit:'5'];
[sixButton setDigit:'6'];
[sevenButton setDigit:'7'];
[eightButton setDigit:'8'];
[nineButton setDigit:'9'];
[starButton setDigit:'*'];
[sharpButton setDigit:'#'];
[addressField setAdjustsFontSizeToFitWidth:TRUE]; // Not put it in IB: issue with placeholder size
if([LinphoneManager runningOnIpad]) {
if ([LinphoneManager instance].frontCamId != nil) {
// only show camera switch button if we have more than 1 camera
[videoCameraSwitch setHidden:FALSE];
}
}
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
CGRect frame = [videoPreview frame];
switch (toInterfaceOrientation) {
case UIInterfaceOrientationPortrait:
[videoPreview setTransform: CGAffineTransformMakeRotation(0)];
break;
case UIInterfaceOrientationPortraitUpsideDown:
[videoPreview setTransform: CGAffineTransformMakeRotation(M_PI)];
break;
case UIInterfaceOrientationLandscapeLeft:
[videoPreview setTransform: CGAffineTransformMakeRotation(M_PI / 2)];
break;
case UIInterfaceOrientationLandscapeRight:
[videoPreview setTransform: CGAffineTransformMakeRotation(-M_PI / 2)];
break;
default:
break;
}
[videoPreview setFrame:frame];
}
#pragma mark - Event Functions
- (void)callUpdateEvent:(NSNotification*)notif {
LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue];
LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue];
[self callUpdate:call state:state];
}
- (void)coreUpdateEvent:(NSNotification*)notif {
if([LinphoneManager isLcReady] && [LinphoneManager runningOnIpad]) {
LinphoneCore* lc = [LinphoneManager getLc];
if(linphone_core_video_enabled(lc) && linphone_core_video_preview_enabled(lc)) {
linphone_core_set_native_preview_window_id(lc, (unsigned long)videoPreview);
[backgroundView setHidden:FALSE];
[videoCameraSwitch setHidden:FALSE];
} else {
linphone_core_set_native_preview_window_id(lc, (unsigned long)NULL);
[backgroundView setHidden:TRUE];
[videoCameraSwitch setHidden:TRUE];
}
}
}
#pragma mark -
- (void)callUpdate:(LinphoneCall*)call state:(LinphoneCallState)state {
if([LinphoneManager isLcReady]) {
LinphoneCore *lc = [LinphoneManager getLc];
if(linphone_core_get_calls_nb(lc) > 0) {
if(transferMode) {
[addCallButton setHidden:true];
[transferButton setHidden:false];
} else {
[addCallButton setHidden:false];
[transferButton setHidden:true];
}
[callButton setHidden:true];
[backButton setHidden:false];
[addContactButton setHidden:true];
} else {
[addCallButton setHidden:true];
[callButton setHidden:false];
[backButton setHidden:true];
[addContactButton setHidden:false];
[transferButton setHidden:true];
}
}
}
- (void)setAddress:(NSString*) address {
[addressField setText:address];
}
- (void)setTransferMode:(BOOL)atransferMode {
transferMode = atransferMode;
LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]);
LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0;
[self callUpdate:call state:state];
}
- (void)call:(NSString*)address {
NSString *displayName = nil;
ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:address];
if(contact) {
displayName = [FastAddressBook getContactDisplayName:contact];
}
[self call:address displayName:displayName];
}
- (void)call:(NSString*)address displayName:(NSString *)displayName {
[[LinphoneManager instance] call:address displayName:displayName transfer:transferMode];
}
#pragma mark - UITextFieldDelegate Functions
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//[textField performSelector:@selector() withObject:nil afterDelay:0];
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == addressField) {
[addressField resignFirstResponder];
}
return YES;
}
#pragma mark - Action Functions
- (IBAction)onAddContactClick: (id) event {
[ContactSelection setSelectionMode:ContactSelectionModeEdit];
[ContactSelection setAddAddress:[addressField text]];
[ContactSelection setSipFilter:FALSE];
ContactsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription] push:TRUE], ContactsViewController);
if(controller != nil) {
}
}
- (IBAction)onBackClick: (id) event {
[[PhoneMainView instance] changeCurrentView:[InCallViewController compositeViewDescription]];
}
- (IBAction)onAddressChange: (id)sender {
if([[addressField text] length] > 0) {
[addContactButton setEnabled:TRUE];
[eraseButton setEnabled:TRUE];
[callButton setEnabled:TRUE];
[addCallButton setEnabled:TRUE];
[transferButton setEnabled:TRUE];
} else {
[addContactButton setEnabled:FALSE];
[eraseButton setEnabled:FALSE];
[callButton setEnabled:FALSE];
[addCallButton setEnabled:FALSE];
[transferButton setEnabled:FALSE];
}
}
@end

View file

@ -18,23 +18,19 @@
*/
#import <UIKit/UIKit.h>
#import "LinphoneAppDelegate.h"
#import "LinphoneUIDelegates.h"
#import "UICompositeViewController.h"
@interface FirstLoginViewController : UIViewController <UITextFieldDelegate,LinphoneUIRegistrationDelegate>{
UIButton* ok;
UIButton* site;
UITextField* username;
UIView* activityIndicator;
@interface FirstLoginViewController : UIViewController<UITextFieldDelegate, UICompositeViewDelegate> {
}
-(void) doOk:(id)sender;
@property (nonatomic, retain) IBOutlet UIButton* ok;
@property (nonatomic, retain) IBOutlet UIButton* site;
@property (nonatomic, retain) IBOutlet UITextField* username;
@property (nonatomic, retain) IBOutlet UITextField* passwd;
@property (nonatomic, retain) IBOutlet UIView* activityIndicator;
- (IBAction)onLoginClick:(id)sender;
- (IBAction)onSiteClick:(id)sender;
@property (nonatomic, retain) IBOutlet UIButton* loginButton;
@property (nonatomic, retain) IBOutlet UIButton* siteButton;
@property (nonatomic, retain) IBOutlet UITextField* usernameField;
@property (nonatomic, retain) IBOutlet UITextField* passwordField;
@property (nonatomic, retain) IBOutlet UIView* waitView;
@end

View file

@ -17,55 +17,152 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "LinphoneManager.h"
#import "FirstLoginViewController.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
@implementation FirstLoginViewController
@synthesize ok;
@synthesize username;
@synthesize passwd;
@synthesize activityIndicator;
@synthesize site;
@synthesize loginButton;
@synthesize siteButton;
@synthesize usernameField;
@synthesize passwordField;
@synthesize waitView;
#pragma mark - Lifecycle Functions
- (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"];
if (siteUrl==nil) {
siteUrl=@"http://www.linphone.org";
}
[site setTitle:siteUrl forState:UIControlStateNormal];
- (id)init {
return [super initWithNibName:@"FirstLoginViewController" bundle:[NSBundle mainBundle]];
}
- (void)dealloc {
[loginButton release];
[siteButton release];
[usernameField release];
[passwordField release];
[waitView release];
// Remove all observer
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
[ok dealloc];
[site dealloc];
[username dealloc];
[activityIndicator dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
-(void) doOk:(id)sender {
if (sender == site) {
NSURL *url = [NSURL URLWithString:site.titleLabel.text];
[[UIApplication sharedApplication] openURL:url];
return;
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"FirstLogin"
content:@"FirstLoginViewController"
stateBar:nil
stateBarEnabled:false
tabBar:nil
tabBarEnabled:false
fullscreen:false
landscapeMode:false
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Set observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(registrationUpdateEvent:)
name:kLinphoneRegistrationUpdate
object:nil];
[usernameField setText:[[LinphoneManager instance] lpConfigStringForKey:@"wizard_username"]];
[passwordField setText:[[LinphoneManager instance] lpConfigStringForKey:@"wizard_password"]];
// Update on show
const MSList* list = linphone_core_get_proxy_config_list([LinphoneManager getLc]);
if(list != NULL) {
LinphoneProxyConfig *config = (LinphoneProxyConfig*) list->data;
if(config) {
[self registrationUpdate:linphone_proxy_config_get_state(config)];
}
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneRegistrationUpdate
object:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
NSString* siteUrl = [[LinphoneManager instance] lpConfigStringForKey:@"first_login_view_url"];
if (siteUrl==nil) {
siteUrl=@"http://www.linphone.org";
}
[siteButton setTitle:siteUrl forState:UIControlStateNormal];
}
#pragma mark - Event Functions
- (void)registrationUpdateEvent:(NSNotification*)notif {
[self registrationUpdate:[[notif.userInfo objectForKey: @"state"] intValue]];
}
#pragma mark -
- (void)registrationUpdate:(LinphoneRegistrationState)state {
switch (state) {
case LinphoneRegistrationOk: {
[[LinphoneManager instance] lpConfigSetBool:FALSE forKey:@"enable_first_login_view_preference"];
[waitView setHidden:true];
[[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]];
break;
}
case LinphoneRegistrationNone:
case LinphoneRegistrationCleared: {
[waitView setHidden:true];
break;
}
case LinphoneRegistrationFailed: {
[waitView setHidden:true];
//erase uername passwd
[[LinphoneManager instance] lpConfigSetString:nil forKey:@"wizard_username"];
[[LinphoneManager instance] lpConfigSetString:nil forKey:@"wizard_password"];
break;
}
case LinphoneRegistrationProgress: {
[waitView setHidden:false];
break;
}
default: break;
}
}
#pragma mark - Action Functions
- (void)onSiteClick:(id)sender {
NSURL *url = [NSURL URLWithString:siteButton.titleLabel.text];
[[UIApplication sharedApplication] openURL:url];
return;
}
- (void)onLoginClick:(id)sender {
NSString* errorMessage=nil;
if ([username.text length]==0 ) {
if ([usernameField.text length]==0 ) {
errorMessage=NSLocalizedString(@"Enter your username",nil);
} else if ([passwd.text length]==0 ) {
} else if ([passwordField.text length]==0 ) {
errorMessage=NSLocalizedString(@"Enter your password",nil);
}
@ -79,47 +176,31 @@
[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];
[self.activityIndicator setHidden:false];
linphone_core_clear_all_auth_info([LinphoneManager getLc]);
linphone_core_clear_proxy_config([LinphoneManager getLc]);
LinphoneProxyConfig* proxyCfg = linphone_core_create_proxy_config([LinphoneManager getLc]);
/*default domain is supposed to be preset from linphonerc*/
NSString* identity = [NSString stringWithFormat:@"sip:%@@%s",usernameField.text, linphone_proxy_config_get_addr(proxyCfg)];
linphone_proxy_config_set_identity(proxyCfg,[identity UTF8String]);
LinphoneAuthInfo* auth_info =linphone_auth_info_new([usernameField.text UTF8String]
,[usernameField.text UTF8String]
,[passwordField.text UTF8String]
,NULL
,NULL);
linphone_core_add_auth_info([LinphoneManager getLc], auth_info);
linphone_core_add_proxy_config([LinphoneManager getLc], proxyCfg);
linphone_core_set_default_proxy([LinphoneManager getLc], proxyCfg);
[self.waitView setHidden:false];
};
}
-(void) displayRegisteredFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName onDomain:(NSString*)domain {
[[NSUserDefaults standardUserDefaults] setBool:false forKey:@"enable_first_login_view_preference"];
[self.activityIndicator setHidden:true];
[self dismissModalViewControllerAnimated:YES];
}
-(void) displayRegisteringFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName onDomain:(NSString*)domain {
[self.activityIndicator setHidden:false];
}
-(void) displayRegistrationFailedFromUI:(UIViewController*) viewCtrl forUser:(NSString*) user withDisplayName:(NSString*) displayName onDomain:(NSString*)domain forReason:(NSString*) reason {
[self.activityIndicator setHidden:true];
//default behavior if no registration delegates
//UIAlertView* error = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"Registration failure for user %@",user]
// message:reason
// delegate:nil
// cancelButtonTitle:@"Continue"
// otherButtonTitles:nil ,nil];
//[error show];
//[error release];
//erase uername passwd
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"username_preference"];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"password_preference"];
}
-(void) displayNotRegisteredFromUI:(UIViewController*) viewCtrl {
[self.activityIndicator setHidden:true];
}
#pragma mark - UITextFieldDelegate Functions
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
// When the user presses return, take focus away from the text field so that the keyboard is dismissed.
[theTextField resignFirstResponder];
return YES;
}
@end

View file

@ -1,500 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">784</int>
<string key="IBDocument.SystemVersion">10K549</string>
<string key="IBDocument.InterfaceBuilderVersion">1938</string>
<string key="IBDocument.AppKitVersion">1038.36</string>
<string key="IBDocument.HIToolboxVersion">461.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">933</string>
</object>
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>IBUIView</string>
<string>IBUIImageView</string>
<string>IBUIViewController</string>
<string>IBProxyObject</string>
<string>IBUIActivityIndicatorView</string>
<string>IBUITextField</string>
<string>IBUIButton</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIViewController" id="284579969">
<object class="IBUIView" key="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIImageView" id="427931982">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{0, -20}, {360, 480}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSNextKeyView" ref="210410556"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<int key="IBUIContentMode">9</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">wallpaper_iphone_320x480.png</string>
</object>
</object>
<object class="IBUIButton" id="731646357">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">-2147483356</int>
<string key="NSFrame">{{60, 400}, {200, 37}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSNextKeyView"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<object class="NSColor" key="IBUIHighlightedTitleColor" id="992101396">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor" id="64173324">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<string key="name">Helvetica-Bold</string>
<string key="family">Helvetica</string>
<int key="traits">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUITextField" id="415396672">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{60, 200}, {200, 31}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSNextKeyView" ref="157624641"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<string key="IBUIText"/>
<int key="IBUIBorderStyle">3</int>
<string key="IBUIPlaceholder">Password</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace" id="925734638">
<int key="NSID">2</int>
</object>
</object>
<bool key="IBUIClearsOnBeginEditing">YES</bool>
<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
<float key="IBUIMinimumFontSize">17</float>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<int key="IBUIAutocorrectionType">1</int>
<bool key="IBUISecureTextEntry">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="927759199">
<int key="type">1</int>
<double key="pointSize">12</double>
</object>
<object class="NSFont" key="IBUIFont" id="348267750">
<string key="NSName">Helvetica</string>
<double key="NSSize">12</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUITextField" id="300056741">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{60, 150}, {200, 31}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSNextKeyView" ref="415396672"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentVerticalAlignment">0</int>
<string key="IBUIText"/>
<int key="IBUIBorderStyle">3</int>
<string key="IBUIPlaceholder">Username</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
<reference key="NSCustomColorSpace" ref="925734638"/>
</object>
<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
<float key="IBUIMinimumFontSize">17</float>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<int key="IBUIAutocorrectionType">1</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<reference key="IBUIFontDescription" ref="927759199"/>
<reference key="IBUIFont" ref="348267750"/>
</object>
<object class="IBUIButton" id="157624641">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{60, 300}, {200, 37}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSNextKeyView" ref="731646357"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">1</int>
<string key="IBUINormalTitle">Login</string>
<reference key="IBUIHighlightedTitleColor" ref="992101396"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">5</int>
<bytes key="NSCMYK">MSAwLjY2MDAwMDAyNjIgMCAwAA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">3</int>
</object>
<characters key="NSComponents">1 0.66 0 0 1</characters>
</object>
<reference key="IBUINormalTitleShadowColor" ref="64173324"/>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<int key="size">2</int>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">18</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIView" id="210410556">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">-2147483356</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIActivityIndicatorView" id="871218378">
<reference key="NSNextResponder" ref="210410556"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{142, 211}, {37, 37}}</string>
<reference key="NSSuperview" ref="210410556"/>
<reference key="NSNextKeyView" ref="300056741"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIHidesWhenStopped">NO</bool>
<bool key="IBUIAnimating">YES</bool>
<int key="IBUIStyle">0</int>
</object>
</object>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSNextKeyView" ref="871218378"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MSAwLjY2AA</bytes>
<reference key="NSCustomColorSpace" ref="925734638"/>
</object>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</object>
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
<reference key="NSSuperview"/>
<reference key="NSNextKeyView" ref="427931982"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<reference key="NSCustomColorSpace" ref="925734638"/>
</object>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
<int key="IBUIInterfaceOrientation">1</int>
<int key="interfaceOrientation">1</int>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIHorizontal">NO</bool>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">3</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">passwd</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="415396672"/>
</object>
<int key="connectionID">15</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">activityIndicator</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="210410556"/>
</object>
<int key="connectionID">33</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">username</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="300056741"/>
</object>
<int key="connectionID">38</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">site</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="731646357"/>
</object>
<int key="connectionID">36</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="300056741"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">39</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="415396672"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">17</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">doOk:</string>
<reference key="source" ref="157624641"/>
<reference key="destination" ref="372490531"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">20</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">doOk:</string>
<reference key="source" ref="731646357"/>
<reference key="destination" ref="372490531"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">37</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="284579969"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="191373211"/>
</object>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="157624641"/>
<reference ref="300056741"/>
<reference ref="731646357"/>
<reference ref="415396672"/>
<reference ref="427931982"/>
<reference ref="210410556"/>
</object>
<reference key="parent" ref="284579969"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">12</int>
<reference key="object" ref="157624641"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="300056741"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">username</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">8</int>
<reference key="object" ref="415396672"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">passwd</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="427931982"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">31</int>
<reference key="object" ref="210410556"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="871218378"/>
</object>
<reference key="parent" ref="191373211"/>
<string key="objectName">wait</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">32</int>
<reference key="object" ref="871218378"/>
<reference key="parent" ref="210410556"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">35</int>
<reference key="object" ref="731646357"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">site</string>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.CustomClassName</string>
<string>-1.IBPluginDependency</string>
<string>-2.CustomClassName</string>
<string>-2.IBPluginDependency</string>
<string>1.IBPluginDependency</string>
<string>1.IBUserGuides</string>
<string>12.IBPluginDependency</string>
<string>12.IBUIButtonInspectorSelectedStateConfigurationMetadataKey</string>
<string>31.IBPluginDependency</string>
<string>32.IBPluginDependency</string>
<string>35.IBPluginDependency</string>
<string>4.IBPluginDependency</string>
<string>5.IBPluginDependency</string>
<string>6.IBPluginDependency</string>
<string>8.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>FirstLoginViewController</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>UIResponder</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<object class="NSMutableArray">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUserGuide">
<reference key="view" ref="191373211"/>
<double key="location">104</double>
<int key="affinity">0</int>
</object>
</object>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<real value="0.0"/>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
<int key="maxID">54</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<integer value="784" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1280" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
<integer value="3000" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="NS.key.0">wallpaper_iphone_320x480.png</string>
<string key="NS.object.0">{320, 480}</string>
</object>
<string key="IBCocoaTouchPluginVersion">933</string>
</data>
</archive>

View file

@ -0,0 +1,52 @@
/* HistoryDetailsViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "linphonecore.h"
#import <AddressBook/AddressBook.h>
#import "UICompositeViewController.h"
@interface HistoryDetailsViewController : UIViewController<UICompositeViewDelegate> {
@private
ABRecordRef contact;
NSDateFormatter *dateFormatter;
}
@property (nonatomic, retain) IBOutlet UIImageView *avatarImage;
@property (nonatomic, retain) IBOutlet UILabel *addressLabel;
@property (nonatomic, retain) IBOutlet UILabel *dateLabel;
@property (nonatomic, retain) IBOutlet UILabel *dateHeaderLabel;
@property (nonatomic, retain) IBOutlet UILabel *durationLabel;
@property (nonatomic, retain) IBOutlet UILabel *durationHeaderLabel;
@property (nonatomic, retain) IBOutlet UILabel *typeLabel;
@property (nonatomic, retain) IBOutlet UILabel *typeHeaderLabel;
@property (nonatomic, retain) IBOutlet UILabel *plainAddressLabel;
@property (nonatomic, retain) IBOutlet UILabel *plainAddressHeaderLabel;
@property (nonatomic, retain) IBOutlet UIButton *callButton;
@property (nonatomic, retain) IBOutlet UIButton *messageButton;
@property (nonatomic, retain) IBOutlet UIButton *addContactButton;
@property (nonatomic, assign) LinphoneCallLog *callLog;
- (IBAction)onBackClick:(id)event;
- (IBAction)onContactClick:(id)event;
- (IBAction)onAddContactClick:(id)event;
- (IBAction)onCallClick:(id)event;
- (IBAction)onMessageClick:(id)event;
@end

View file

@ -0,0 +1,381 @@
/* HistoryDetailsViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "HistoryDetailsViewController.h"
#import "PhoneMainView.h"
#import "FastAddressBook.h"
#import "Utils.h"
@implementation HistoryDetailsViewController
@synthesize callLog;
@synthesize avatarImage;
@synthesize addressLabel;
@synthesize dateLabel;
@synthesize dateHeaderLabel;
@synthesize durationLabel;
@synthesize durationHeaderLabel;
@synthesize typeLabel;
@synthesize typeHeaderLabel;
@synthesize plainAddressLabel;
@synthesize plainAddressHeaderLabel;
@synthesize callButton;
@synthesize messageButton;
@synthesize addContactButton;
#pragma mark - LifeCycle Functions
- (id)init {
self = [super initWithNibName:@"HistoryDetailsViewController" bundle:[NSBundle mainBundle]];
if(self != nil) {
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSLocale *locale = [NSLocale currentLocale];
[dateFormatter setLocale:locale];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[dateFormatter release];
[avatarImage release];
[addressLabel release];
[dateLabel release];
[dateHeaderLabel release];
[durationLabel release];
[durationHeaderLabel release];
[typeLabel release];
[typeHeaderLabel release];
[plainAddressLabel release];
[plainAddressHeaderLabel release];
[callButton release];
[messageButton release];
[addContactButton release];
[super dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"HistoryDetails"
content:@"HistoryDetailsViewController"
stateBar:nil
stateBarEnabled:false
tabBar:@"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - Property Functions
- (void)setCallLog:(LinphoneCallLog *)acallLog {
self->callLog = acallLog;
[self update];
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[super viewDidLoad];
[HistoryDetailsViewController adaptSize:dateHeaderLabel field:dateLabel];
[HistoryDetailsViewController adaptSize:durationHeaderLabel field:durationLabel];
[HistoryDetailsViewController adaptSize:typeHeaderLabel field:typeLabel];
[HistoryDetailsViewController adaptSize:plainAddressHeaderLabel field:plainAddressLabel];
[callButton.titleLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack!
[messageButton.titleLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack!
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(update:)
name:kLinphoneAddressBookUpdate
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneAddressBookUpdate
object:nil];
}
#pragma mark -
+ (void)adaptSize:(UILabel*)label field:(UIView*)field {
//
// Adapt size
//
CGRect labelFrame = [label frame];
CGRect fieldFrame = [field frame];
fieldFrame.origin.x -= labelFrame.size.width;
// Compute firstName size
CGSize contraints;
contraints.height = [label frame].size.height;
contraints.width = ([field frame].size.width + [field frame].origin.x) - [label frame].origin.x;
CGSize firstNameSize = [[label text] sizeWithFont:[label font] constrainedToSize: contraints];
labelFrame.size.width = firstNameSize.width;
// Compute lastName size & position
fieldFrame.origin.x += labelFrame.size.width;
fieldFrame.size.width = (contraints.width + [label frame].origin.x) - fieldFrame.origin.x;
[label setFrame: labelFrame];
[field setFrame: fieldFrame];
}
- (void)update {
// Don't update if callLog is null
if(callLog == NULL) {
return;
}
LinphoneAddress* addr = NULL;
if (callLog->dir == LinphoneCallIncoming) {
addr = callLog->from;
} else {
addr = callLog->to;
}
UIImage *image = nil;
NSString* address = nil;
if(addr != NULL) {
BOOL useLinphoneAddress = true;
// contact name
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress) {
NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]];
contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress];
if(contact) {
image = [FastAddressBook getContactImage:contact thumbnail:true];
address = [FastAddressBook getContactDisplayName:contact];
useLinphoneAddress = false;
}
ms_free(lAddress);
}
if(useLinphoneAddress) {
const char* lDisplayName = linphone_address_get_display_name(addr);
const char* lUserName = linphone_address_get_username(addr);
if (lDisplayName)
address = [NSString stringWithUTF8String:lDisplayName];
else if(lUserName)
address = [NSString stringWithUTF8String:lUserName];
}
}
// Set Image
if(image == nil) {
image = [UIImage imageNamed:@"avatar_unknown.png"];
}
[avatarImage setImage:image];
// Set Address
if(address == nil) {
address = NSLocalizedString(@"Unknown", nil);
}
[addressLabel setText:address];
// Hide/Show add button
if(contact) {
[addContactButton setHidden:TRUE];
} else {
[addContactButton setHidden:FALSE];
}
// State
NSMutableString *state = [NSMutableString string];
if (callLog->dir == LinphoneCallIncoming) {
[state setString:NSLocalizedString(@"Incoming call", nil)];
} else {
[state setString:NSLocalizedString(@"Outgoing call", nil)];
}
switch (callLog->status) {
case LinphoneCallSuccess:
break;
case LinphoneCallAborted:
[state appendString:NSLocalizedString(@" (Aborted)", nil)];
break;
case LinphoneCallMissed:
[state appendString:NSLocalizedString(@" (Missed)", nil)];
break;
case LinphoneCallDeclined:
[state appendString:NSLocalizedString(@" (Declined)", nil)];
break;
}
[typeLabel setText:state];
// Date
NSDate *startData = [NSDate dateWithTimeIntervalSince1970:callLog->start_date_time];
[dateLabel setText:[dateFormatter stringFromDate:startData]];
// Duration
int duration = callLog->duration;
[durationLabel setText:[NSString stringWithFormat:@"%02i:%02i", (duration/60), duration - 60 * (duration / 60), nil]];
// contact name
[plainAddressLabel setText:@""];
if (addr != NULL) {
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress != NULL) {
[plainAddressLabel setText:[NSString stringWithUTF8String:lAddress]];
ms_free(lAddress);
} else {
}
}
if (addr != NULL) {
[callButton setHidden:FALSE];
[messageButton setHidden:FALSE];
} else {
[callButton setHidden:TRUE];
[messageButton setHidden:TRUE];
}
}
#pragma mark - Action Functions
- (IBAction)onBackClick:(id)event {
[[PhoneMainView instance] popCurrentView];
}
- (IBAction)onContactClick:(id)event {
if(contact) {
ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController);
if(controller != nil) {
[ContactSelection setSelectionMode:ContactSelectionModeNone];
[controller setContact:contact];
}
}
}
- (IBAction)onAddContactClick:(id)event {
LinphoneAddress* addr = NULL;
if (callLog->dir == LinphoneCallIncoming) {
addr = callLog->from;
} else {
addr = callLog->to;
}
if (addr != NULL) {
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress != NULL) {
[ContactSelection setAddAddress:[NSString stringWithUTF8String:lAddress]];
[ContactSelection setSelectionMode:ContactSelectionModeEdit];
[ContactSelection setSipFilter:FALSE];
ContactsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription] push:TRUE], ContactsViewController);
if(controller != nil) {
}
ms_free(lAddress);
}
}
}
- (IBAction)onCallClick:(id)event {
LinphoneAddress* addr;
if (callLog->dir == LinphoneCallIncoming) {
addr = callLog->from;
} else {
addr = callLog->to;
}
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress == NULL)
return;
NSString *displayName = nil;
if(contact != nil) {
displayName = [FastAddressBook getContactDisplayName:contact];
} else {
const char* lDisplayName = linphone_address_get_display_name(addr);
const char* lUserName = linphone_address_get_username(addr);
if (lDisplayName)
displayName = [NSString stringWithUTF8String:lDisplayName];
else if(lUserName)
displayName = [NSString stringWithUTF8String:lUserName];
}
DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
if(controller != nil) {
if(displayName != nil) {
[controller call:[NSString stringWithUTF8String:lAddress] displayName:displayName];
} else {
[controller call:[NSString stringWithUTF8String:lAddress]];
}
}
ms_free(lAddress);
}
- (IBAction)onMessageClick:(id)event {
LinphoneAddress* addr;
if (callLog->dir == LinphoneCallIncoming) {
addr = callLog->from;
} else {
addr = callLog->to;
}
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress == NULL)
return;
NSString *displayName = nil;
if(contact != nil) {
displayName = [FastAddressBook getContactDisplayName:contact];
} else {
const char* lDisplayName = linphone_address_get_display_name(addr);
const char* lUserName = linphone_address_get_username(addr);
if (lDisplayName)
displayName = [NSString stringWithUTF8String:lDisplayName];
else if(lUserName)
displayName = [NSString stringWithUTF8String:lUserName];
}
// Go to ChatRoom view
[[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]];
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
if(controller != nil) {
[controller setRemoteAddress:[NSString stringWithUTF8String:lAddress]];
}
ms_free(lAddress);
}
@end

View file

@ -1,4 +1,4 @@
/* CallHistoryTableViewController.h
/* HistoryTableViewController.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
@ -16,14 +16,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "GenericTabViewController.h"
@interface CallHistoryTableViewController : GenericTabViewController {
UIButton* clear;
@interface HistoryTableViewController : UITableViewController {
@private
NSMutableArray *callLogs;
}
-(void) doAction:(id) sender;
- (void)loadData;
@property (nonatomic, assign) BOOL missedFilter;
@property (nonatomic, retain) IBOutlet UIButton* clear;
@end

View file

@ -0,0 +1,193 @@
/* HistoryTableViewController.m
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "HistoryTableViewController.h"
#import "UIHistoryCell.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import "UACellBackgroundView.h"
#import "UILinphone.h"
#import "Utils.h"
@implementation HistoryTableViewController
@synthesize missedFilter;
#pragma mark - Lifecycle Functions
- (void)initHistoryTableViewController {
callLogs = [[NSMutableArray alloc] init];
missedFilter = false;
}
- (id)init {
self = [super init];
if (self) {
[self initHistoryTableViewController];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self initHistoryTableViewController];
}
return self;
}
- (void)dealloc {
[callLogs release];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self loadData];
}
#pragma mark - Property Functions
- (void)setMissedFilter:(BOOL)amissedFilter {
if(missedFilter == amissedFilter) {
return;
}
missedFilter = amissedFilter;
[self loadData];
}
#pragma mark - UITableViewDataSource Functions
- (void)loadData {
[callLogs removeAllObjects];
const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]);
while(logs != NULL) {
LinphoneCallLog* log = (LinphoneCallLog *) logs->data;
if(missedFilter) {
if (log->status == LinphoneCallMissed) {
[callLogs addObject:[NSValue valueWithPointer: log]];
}
} else {
[callLogs addObject:[NSValue valueWithPointer: log]];
}
logs = ms_list_next(logs);
}
[[self tableView] reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [callLogs count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"UIHistoryCell";
UIHistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[[UIHistoryCell alloc] initWithIdentifier:kCellId] autorelease];
// Background View
UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView = selectedBackgroundView;
[selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR];
}
LinphoneCallLog *log = [[callLogs objectAtIndex:[indexPath row]] pointerValue];
[cell setCallLog:log];
return cell;
}
#pragma mark - UITableViewDelegate Functions
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
LinphoneCallLog *callLog = [[callLogs objectAtIndex:[indexPath row]] pointerValue];
LinphoneAddress* addr;
if (callLog->dir == LinphoneCallIncoming) {
addr = callLog->from;
} else {
addr = callLog->to;
}
NSString* displayName = nil;
NSString* address = nil;
if(addr != NULL) {
BOOL useLinphoneAddress = true;
// contact name
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress) {
address = [NSString stringWithUTF8String:lAddress];
NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:address];
ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress];
if(contact) {
displayName = [FastAddressBook getContactDisplayName:contact];
useLinphoneAddress = false;
}
ms_free(lAddress);
}
if(useLinphoneAddress) {
const char* lDisplayName = linphone_address_get_display_name(addr);
const char* lUserName = linphone_address_get_username(addr);
if (lDisplayName)
displayName = [NSString stringWithUTF8String:lDisplayName];
else if(lUserName)
displayName = [NSString stringWithUTF8String:lUserName];
}
}
if(address != nil) {
// Go to dialer view
DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
if(controller != nil) {
[controller call:address displayName:displayName];
}
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
// Detemine if it's in editing mode
if (self.editing) {
return UITableViewCellEditingStyleDelete;
}
return UITableViewCellEditingStyleNone;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
LinphoneCallLog *callLog = [[callLogs objectAtIndex:[indexPath row]] pointerValue];
linphone_core_remove_call_log([LinphoneManager getLc], callLog);
[callLogs removeObjectAtIndex:[indexPath row]];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
}
@end

View file

@ -0,0 +1,42 @@
/* HistoryViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UICompositeViewController.h"
#import "HistoryTableViewController.h"
#import "UIToggleButton.h"
@interface HistoryViewController : UIViewController<UICompositeViewDelegate> {
}
@property (nonatomic, retain) IBOutlet HistoryTableViewController* tableController;
@property (nonatomic, retain) IBOutlet UITableView *tableView;
@property (nonatomic, retain) IBOutlet UIButton* allButton;
@property (nonatomic, retain) IBOutlet UIButton* missedButton;
@property (nonatomic, retain) IBOutlet UIToggleButton* editButton;
@property (nonatomic, retain) IBOutlet UIButton* deleteButton;
- (IBAction)onAllClick:(id) event;
- (IBAction)onMissedClick:(id) event;
- (IBAction)onEditClick:(id) event;
- (IBAction)onDeleteClick:(id) event;
@end

View file

@ -0,0 +1,190 @@
/* HistoryViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "HistoryViewController.h"
@implementation HistoryViewController
@synthesize tableView;
@synthesize tableController;
@synthesize allButton;
@synthesize missedButton;
@synthesize editButton;
@synthesize deleteButton;
typedef enum _HistoryView {
History_All,
History_Missed,
History_MAX
} HistoryView;
#pragma mark - Lifecycle Functions
- (id)init {
return [super initWithNibName:@"HistoryViewController" bundle:[NSBundle mainBundle]];
}
- (void)dealloc {
[tableController release];
[tableView release];
[allButton release];
[missedButton release];
[editButton release];
[deleteButton release];
[super dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"History"
content:@"HistoryViewController"
stateBar:nil
stateBarEnabled:false
tabBar:@"UIMainBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewWillAppear:animated];
}
if([tableController isEditing]) {
[tableController setEditing:FALSE animated:FALSE];
}
[deleteButton setHidden:TRUE];
[editButton setOff];
[self changeView: History_All];
// Reset missed call
linphone_core_reset_missed_calls_count([LinphoneManager getLc]);
// Fake event
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewDidAppear:animated];
}
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewDidDisappear:animated];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[tableController viewWillDisappear:animated];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[self changeView: History_All];
// Set selected+over background: IB lack !
[editButton setBackgroundImage:[UIImage imageNamed:@"history_ok_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:editButton];
// Set selected+over background: IB lack !
[allButton setBackgroundImage:[UIImage imageNamed:@"history_all_selected.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStatesForTabs:allButton];
// Set selected+over background: IB lack !
[missedButton setBackgroundImage:[UIImage imageNamed:@"history_missed_selected.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStatesForTabs:missedButton];
[tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
[tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4
}
#pragma mark -
- (void)changeView: (HistoryView) view {
if(view == History_All) {
allButton.selected = TRUE;
[tableController setMissedFilter:FALSE];
} else {
allButton.selected = FALSE;
}
if(view == History_Missed) {
missedButton.selected = TRUE;
[tableController setMissedFilter:TRUE];
} else {
missedButton.selected = FALSE;
}
}
#pragma mark - Action Functions
- (IBAction)onAllClick:(id) event {
[self changeView: History_All];
}
- (IBAction)onMissedClick:(id) event {
[self changeView: History_Missed];
}
- (IBAction)onEditClick:(id) event {
[tableController setEditing:![tableController isEditing] animated:TRUE];
[deleteButton setHidden:![tableController isEditing]];
}
- (IBAction)onDeleteClick:(id) event {
linphone_core_clear_call_logs([LinphoneManager getLc]);
[tableController loadData];
if([editButton isSelected]) {
[editButton toggle];
[self onEditClick:nil];
}
}
@end

View file

@ -0,0 +1,39 @@
/* ImagePickerViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "UICompositeViewController.h"
@protocol ImagePickerDelegate <NSObject>
- (void)imagePickerDelegateImage:(UIImage*)image info:(NSDictionary *)info;
@end
@interface ImagePickerViewController : UIViewController <UICompositeViewDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIPopoverControllerDelegate> {
@private
UIImagePickerController *pickerController;
}
@property(nonatomic, retain) id<ImagePickerDelegate> imagePickerDelegate;
@property(nonatomic) UIImagePickerControllerSourceType sourceType;
@property(nonatomic,copy) NSArray *mediaTypes;
@property(nonatomic) BOOL allowsEditing;
@property(nonatomic, readonly) UIPopoverController *popoverController;
@end

View file

@ -0,0 +1,193 @@
/* ImagePickerViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ImagePickerViewController.h"
#import "PhoneMainView.h"
#import "DTActionSheet.h"
@implementation ImagePickerViewController
@synthesize imagePickerDelegate;
@synthesize sourceType;
@synthesize mediaTypes;
@synthesize allowsEditing;
@synthesize popoverController;
#pragma mark - Lifecycle Functions
- (id)init {
self = [super init];
if (self != nil) {
pickerController = [[UIImagePickerController alloc] init];
if([LinphoneManager runningOnIpad]) {
popoverController = [[UIPopoverController alloc] initWithContentViewController:pickerController];
}
}
return self;
}
- (void)dealloc {
[pickerController release];
[popoverController release];
[super dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"ImagePicker"
content:@"ImagePickerViewController"
stateBar:nil
stateBarEnabled:false
tabBar:nil
tabBarEnabled:false
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
if(popoverController == nil) {
[pickerController.view setFrame:[self.view bounds]];
[self.view addSubview:[pickerController view]];
} else {
[popoverController setDelegate:self];
}
[pickerController setDelegate:self];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[pickerController viewWillAppear:animated];
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if(popoverController != nil) {
[popoverController presentPopoverFromRect:CGRectZero inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:FALSE];
} else if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[pickerController viewDidAppear:animated];
}
[[UIApplication sharedApplication] setStatusBarHidden:NO]; //Fix UIImagePickerController status bar hide
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque]; //Fix UIImagePickerController status bar style change
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[pickerController viewDidDisappear:animated];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if(popoverController != nil) {
[popoverController dismissPopoverAnimated: NO];
} else if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[pickerController viewWillDisappear:animated];
}
}
#pragma mark - Property Functions
- (BOOL)allowsEditing {
return pickerController.allowsEditing;
}
- (void)setAllowsEditing:(BOOL)aallowsEditing {
pickerController.allowsEditing = aallowsEditing;
}
- (UIImagePickerControllerSourceType)sourceType {
return pickerController.sourceType;
}
- (void)setSourceType:(UIImagePickerControllerSourceType)asourceType {
pickerController.sourceType = asourceType;
}
- (NSArray *)mediaTypes {
return pickerController.mediaTypes;
}
- (void)setMediaTypes:(NSArray *)amediaTypes {
pickerController.mediaTypes = amediaTypes;
}
#pragma mark -
- (void)dismiss {
if([[[PhoneMainView instance] currentView] equal:[ImagePickerViewController compositeViewDescription]]) {
[[PhoneMainView instance] popCurrentView];
}
}
#pragma mark - UIImagePickerControllerDelegate Functions
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismiss];
UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
if(image == nil) {
image = [info objectForKey:UIImagePickerControllerOriginalImage];
}
if(image != nil && imagePickerDelegate != nil) {
[imagePickerDelegate imagePickerDelegateImage:image info:info];
}
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self dismiss];
}
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)apopoverController {
[self dismiss];
return TRUE;
}
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated {
if ([navigationController isKindOfClass:[UIImagePickerController class]]) {
[[UIApplication sharedApplication] setStatusBarHidden:NO]; //Fix UIImagePickerController status bar hide
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque]; //Fix UIImagePickerController status bar style change
}
}
@end

52
Classes/ImageSharing.h Normal file
View file

@ -0,0 +1,52 @@
/* ImageSharing.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <Foundation/Foundation.h>
@class ImageSharing;
@protocol ImageSharingDelegate <NSObject>
- (void)imageSharingProgress:(ImageSharing*)imageSharing progress:(float)progress;
- (void)imageSharingAborted:(ImageSharing*)imageSharing;
- (void)imageSharingError:(ImageSharing*)imageSharing error:(NSError *)error;
- (void)imageSharingUploadDone:(ImageSharing*)imageSharing url:(NSURL*)url;
- (void)imageSharingDownloadDone:(ImageSharing*)imageSharing image:(UIImage *)image;
@end
@interface ImageSharing : NSObject<NSURLConnectionDataDelegate> {
@private
NSInteger totalBytesExpectedToRead;
id<ImageSharingDelegate> delegate;
int statusCode;
}
+ (id)imageSharingUpload:(NSURL*)url image:(UIImage*)image delegate:(id<ImageSharingDelegate>)delegate userInfo:(id)userInfo;
+ (id)imageSharingDownload:(NSURL*)url delegate:(id<ImageSharingDelegate>)delegate userInfo:(id)userInfo;
- (void)cancel;
@property (nonatomic, retain) id userInfo;
@property (nonatomic, readonly) BOOL upload;
@property (nonatomic, readonly) NSMutableData* data;
@property (nonatomic, readonly) NSURLConnection* connection;
@end

186
Classes/ImageSharing.m Normal file
View file

@ -0,0 +1,186 @@
/* ImageSharing.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ImageSharing.h"
#import "Utils.h"
#import "LinphoneManager.h"
@implementation ImageSharing
@synthesize connection;
@synthesize data;
@synthesize upload;
@synthesize userInfo;
#pragma mark - Lifecycle Functions
+ (id)imageSharingUpload:(NSURL*)url image:(UIImage*)image delegate:(id<ImageSharingDelegate>)delegate userInfo:(id)auserInfo{
ImageSharing *imgs = [[ImageSharing alloc] init];
if(imgs != nil) {
imgs.userInfo = auserInfo;
imgs->upload = TRUE;
imgs->delegate = [delegate retain];
imgs->data = [[NSMutableData alloc] init];
if(delegate) {
[delegate imageSharingProgress:imgs progress:0];
}
[imgs uploadImageTo:url image:image];
}
return imgs;
}
+ (id)imageSharingDownload:(NSURL*)url delegate:(id<ImageSharingDelegate>)delegate userInfo:(id)auserInfo{
ImageSharing *imgs = [[ImageSharing alloc] init];
if(imgs != nil) {
imgs.userInfo = auserInfo;
imgs->upload = FALSE;
imgs->delegate = [delegate retain];
imgs->data = [[NSMutableData alloc] init];
if(delegate) {
[delegate imageSharingProgress:imgs progress:0];
}
[imgs downloadImageFrom:url];
}
return imgs;
}
- (void)dealloc {
[connection release];
[data release];
[delegate release];
[userInfo release];
[super dealloc];
}
#pragma mark -
- (void)cancel {
[connection cancel];
[LinphoneLogger log:LinphoneLoggerLog format:@"File transfer interrupted by user"];
if(delegate) {
[delegate imageSharingAborted:self];
}
}
- (void)downloadImageFrom:(NSURL*)url {
[LinphoneLogger log:LinphoneLoggerLog format:@"downloading [%@]", [url absoluteString]];
NSURLRequest* request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
connection = [[NSURLConnection alloc] initWithRequest:request delegate: self];
}
- (void)uploadImageTo:(NSURL*)url image:(UIImage*)image {
[LinphoneLogger log:LinphoneLoggerLog format:@"downloading [%@]", [url absoluteString]];
// setting up the request object now
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:url];
[request setHTTPMethod:@"POST"];
/*
add some header info now
we always need a boundary when we post a file
also we need to set the content type
You might want to generate a random boundary.. this is just the same
as my output from wireshark on a valid html post
*/
NSString *boundary = @"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
/*
now lets create the body of the post
*/
NSMutableData *body = [NSMutableData data];
NSString *imageName = [NSString stringWithFormat:@"%i.jpg", [image hash]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@\"\r\n",imageName] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:UIImageJPEGRepresentation(image, 1.0)]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
connection = [[NSURLConnection alloc] initWithRequest:(NSURLRequest *)request delegate:self];
}
#pragma mark - NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)aconnection didFailWithError:(NSError *)error {
if(delegate) {
[delegate imageSharingError:self error:error];
}
[self release];
}
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
if(upload && delegate) {
[delegate imageSharingProgress:self progress:(float)totalBytesWritten/(float)totalBytesExpectedToWrite];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)adata {
[data appendData:adata];
if(!upload && delegate) {
[delegate imageSharingProgress:self progress:(float)data.length/(float)totalBytesExpectedToRead];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response;
statusCode = httpResponse.statusCode;
[LinphoneLogger log:LinphoneLoggerLog format:@"File transfer status code [%i]", statusCode];
if (statusCode == 200 && !upload) {
totalBytesExpectedToRead = [response expectedContentLength];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if(statusCode >= 400) {
NSError *error = [NSError errorWithDomain:@"ImageSharing" code:statusCode userInfo:nil];
if(delegate) {
[delegate imageSharingError:self error:error];
}
return;
}
if (upload) {
NSString* imageRemoteUrl = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[LinphoneLogger log:LinphoneLoggerLog format:@"File can be downloaded from [%@]", imageRemoteUrl];
if(delegate) {
[delegate imageSharingUploadDone:self url:[NSURL URLWithString:imageRemoteUrl]];
}
} else {
UIImage* image = [UIImage imageWithData:data];
[LinphoneLogger log:LinphoneLoggerLog format:@"File downloaded"];
if(delegate) {
[delegate imageSharingDownloadDone:self image:image];
}
}
[self release];
}
@end

View file

@ -1,6 +1,6 @@
/* MainScreenWithVideoPreview.h
/* ImageViewController.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,27 +15,27 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
*/
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "PhoneViewController.h"
@interface MainScreenWithVideoPreview : UIViewController {
UIWindow *window;
PhoneViewController* phoneMainView;
#import "UICompositeViewController.h"
@interface UIImageScrollView : UIScrollView<UIScrollViewDelegate>
AVCaptureSession* session;
AVCaptureDeviceInput* input;
int currentCamera;
@property (nonatomic, retain) UIImage *image;
@property (readonly) IBOutlet UIImageView *imageView;
@end
@interface ImageViewController : UIViewController<UICompositeViewDelegate> {
}
-(void) showPreview:(BOOL) show;
@property (nonatomic, retain) IBOutlet UIImageScrollView *scrollView;
@property (nonatomic, retain) UIImage *image;
@property (nonatomic, retain) IBOutlet UIButton *backButton;
-(void) useCameraAtIndex:(NSInteger)camIndex startSession:(BOOL)start;
- (IBAction)onBackClick:(id)sender;
@property (nonatomic, retain) IBOutlet PhoneViewController* phoneMainView;
@property (nonatomic, retain) IBOutlet UIWindow *window;
@end
@end

View file

@ -0,0 +1,183 @@
/* ImageViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "ImageViewController.h"
#import "PhoneMainView.h"
@implementation UIImageScrollView
@synthesize image;
@synthesize imageView;
#pragma mark - Lifecycle Functions
- (void)initUIImageScrollView {
imageView = [[UIImageView alloc] init];
self.delegate = self;
[self addSubview:imageView];
}
- (id)init {
self = [super init];
if(self != nil) {
[self initUIImageScrollView];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if(self != nil) {
[self initUIImageScrollView];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if(self != nil) {
[self initUIImageScrollView];
}
return self;
}
- (void)dealloc {
[image release];
[imageView dealloc];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)layoutSubviews {
[super layoutSubviews];
// center the image as it becomes smaller than the size of the screen
CGSize boundsSize = self.bounds.size;
CGRect frameToCenter = imageView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width)
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
frameToCenter.origin.x = 0;
// center vertically
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.origin.y = 0;
imageView.frame = frameToCenter;
}
#pragma mark - Property Functions
- (void)setImage:(UIImage *)aimage {
self.minimumZoomScale = 0;
self.zoomScale = 1;
CGRect rect = CGRectMake(0, 0, aimage.size.width, aimage.size.height);
imageView.image = aimage;
imageView.frame = rect;
self.contentSize = rect.size;
[self zoomToRect:rect animated:FALSE];
self.minimumZoomScale = self.zoomScale;
}
- (UIImage *)image {
return imageView.image;
}
#pragma mark - UIScrollViewDelegate Functions
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return imageView;
}
@end
@implementation ImageViewController
@synthesize scrollView;
@synthesize backButton;
@synthesize image;
#pragma mark - Lifecycle Functions
- (id)init {
return [super initWithNibName:@"ImageViewController" bundle:[NSBundle mainBundle]];
}
- (void)dealloc {
[scrollView release];
[backButton release];
[image release];
[super dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"ImageView"
content:@"ImageViewController"
stateBar:nil
stateBarEnabled:false
tabBar:nil
tabBarEnabled:false
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - Property Functions
- (void)setImage:(UIImage *)aimage {
scrollView.image = aimage;
}
- (UIImage *)image {
return scrollView.image;
}
#pragma mark - Action Functions
- (IBAction)onBackClick:(id)sender {
if([[[PhoneMainView instance] currentView] equal:[ImageViewController compositeViewDescription]]) {
[[PhoneMainView instance] popCurrentView];
}
}
@end

View file

@ -0,0 +1,34 @@
/* InCallTableViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UICallCell.h"
#include "linphonecore.h"
@interface InCallTableViewController : UITableViewController {
@private
NSTimer *updateTime;
}
- (void)minimizeAll;
- (void)maximizeAll;
@end

View file

@ -0,0 +1,326 @@
/* InCallTableViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "InCallTableViewController.h"
#import "UICallCell.h"
#import "UIConferenceHeader.h"
#import "LinphoneManager.h"
@implementation InCallTableViewController
static NSString *const kLinphoneInCallCellData = @"LinphoneInCallCellData";
enum TableSection {
ConferenceSection = 0,
CallSection = 1
};
#pragma mark - Lifecycle Functions
- (void)initInCallTableViewController {
}
- (id)init{
self = [super init];
if (self) {
[self initInCallTableViewController];
}
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[self initInCallTableViewController];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self initInCallTableViewController];
}
return self;
}
- (void)dealloc {
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
updateTime = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(update)
userInfo:nil
repeats:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (updateTime != nil) {
[updateTime invalidate];
updateTime = nil;
}
}
#pragma mark - Static Functions
+ (bool)isInConference:(LinphoneCall*) call {
if (!call)
return false;
return linphone_call_is_in_conference(call);
}
+ (int)callCount:(LinphoneCore*) lc {
int count = 0;
const MSList* calls = linphone_core_get_calls(lc);
while (calls != 0) {
if (![InCallTableViewController isInConference:((LinphoneCall*)calls->data)]) {
count++;
}
calls = calls->next;
}
return count;
}
+ (LinphoneCall*)retrieveCallAtIndex: (NSInteger) index inConference:(bool) conf{
const MSList* calls = linphone_core_get_calls([LinphoneManager getLc]);
while (calls != 0) {
if ([InCallTableViewController isInConference:(LinphoneCall*)calls->data] == conf) {
if (index == 0)
break;
index--;
}
calls = calls->next;
}
if (calls == 0) {
[LinphoneLogger logc:LinphoneLoggerError format:"Cannot find call with index %d (in conf: %d)", index, conf];
return nil;
} else {
return (LinphoneCall*)calls->data;
}
}
#pragma mark -
- (void)removeCallData:(LinphoneCall*) call {
// Remove data associated with the call
if(call != NULL) {
LinphoneCallAppData* appData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call);
if(appData != NULL) {
[appData->userInfos removeObjectForKey:kLinphoneInCallCellData];
}
}
}
- (UICallCellData*)addCallData:(LinphoneCall*) call {
// Handle data associated with the call
UICallCellData * data = nil;
if(call != NULL) {
LinphoneCallAppData* appData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call);
if(appData != NULL) {
data = [appData->userInfos objectForKey:kLinphoneInCallCellData];
if(data == nil) {
data = [[[UICallCellData alloc] init:call] autorelease];
[appData->userInfos setObject:data forKey:kLinphoneInCallCellData];
}
}
}
return data;
}
- (UICallCellData*)getCallData:(LinphoneCall*) call {
// Handle data associated with the call
UICallCellData * data = nil;
if(call != NULL) {
LinphoneCallAppData* appData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call);
if(appData != NULL) {
data = [appData->userInfos objectForKey:kLinphoneInCallCellData];
}
}
return data;
}
- (void)update {
UITableView *tableView = [self tableView];
for (int section = 0; section < [tableView numberOfSections]; section++) {
for (int row = 0; row < [tableView numberOfRowsInSection:section]; row++) {
NSIndexPath* cellPath = [NSIndexPath indexPathForRow:row inSection:section];
UICallCell* cell = (UICallCell*) [tableView cellForRowAtIndexPath:cellPath];
[cell update];
}
}
}
- (void)minimizeAll {
const MSList *list = linphone_core_get_calls([LinphoneManager getLc]);
while(list != NULL) {
UICallCellData *data = [self getCallData:(LinphoneCall*)list->data];
if(data) {
data->minimize = true;
}
list = list->next;
}
[[self tableView] reloadData];
}
- (void)maximizeAll {
const MSList *list = linphone_core_get_calls([LinphoneManager getLc]);
while(list != NULL) {
UICallCellData *data = [self getCallData:(LinphoneCall*)list->data];
if(data) {
data->minimize = false;
}
list = list->next;
}
[[self tableView] reloadData];
}
#pragma mark - UITableViewDataSource Functions
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"UICallCell";
UICallCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[[UICallCell alloc] initWithIdentifier:kCellId] autorelease];
}
bool inConference = indexPath.section == ConferenceSection;
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* currentCall = linphone_core_get_current_call(lc);
LinphoneCall* call = [InCallTableViewController retrieveCallAtIndex:indexPath.row inConference:inConference];
[cell setData:[self addCallData:call]];
// Update cell
if ([indexPath section] == CallSection && [indexPath row] == 0 && linphone_core_get_conference_size(lc) == 0) {
[cell setFirstCell:true];
} else {
[cell setFirstCell:false];
}
[cell setCurrentCall:(currentCall == call)];
[cell setConferenceCell:inConference];
[cell update];
/*if (linphone_core_get_calls_nb(lc) > 1 || linphone_core_get_conference_size(lc) > 0) {
tableView.scrollEnabled = true;
} else {
tableView.scrollEnabled = false;
}*/
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
int count = 0;
LinphoneCore* lc = [LinphoneManager getLc];
if(section == CallSection) {
count = [InCallTableViewController callCount:lc];
} else {
count = linphone_core_get_conference_size(lc);
if(linphone_core_is_in_conference(lc)) {
count--;
}
}
return count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return @"";
}
- (NSString*)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
return @"";
}
#pragma mark - UITableViewDelegate Functions
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if(section == CallSection) {
return [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
} else if(section == ConferenceSection) {
LinphoneCore* lc = [LinphoneManager getLc];
if(linphone_core_get_conference_size(lc) > 0){
UIConferenceHeader *headerController = [[UIConferenceHeader alloc] init];
[headerController update];
UIView *headerView = [headerController view];
[headerController release];
return headerView;
} else {
return [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}
}
return [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
LinphoneCore* lc = [LinphoneManager getLc];
if(section == CallSection) {
return 0.000001f; // Hack UITableView = 0
} else if(section == ConferenceSection) {
if(linphone_core_get_conference_size(lc) > 0) {
return [UIConferenceHeader getHeight];
}
}
return 0.000001f; // Hack UITableView = 0
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
LinphoneCore* lc = [LinphoneManager getLc];
if(section == CallSection) {
return 0.000001f; // Hack UITableView = 0
} else if(section == ConferenceSection) {
if(linphone_core_get_conference_size(lc) > 0) {
return 20;
}
}
return 0.000001f; // Hack UITableView = 0
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
bool inConference = indexPath.section == ConferenceSection;
LinphoneCall* call = [InCallTableViewController retrieveCallAtIndex:indexPath.row inConference:inConference];
UICallCellData* data = [self getCallData:call];
if(data != nil &&data->minimize)
return [UICallCell getMinimizedHeight];
return [UICallCell getMaximizedHeight];
}
@end

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,50 @@
/* InCallViewController.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "VideoZoomHandler.h"
#import "UICamSwitch.h"
#import "UICompositeViewController.h"
#import "InCallTableViewController.h"
@class VideoViewController;
@interface InCallViewController : UIViewController <UIGestureRecognizerDelegate, UICompositeViewDelegate> {
@private
UITapGestureRecognizer* singleFingerTap;
NSTimer* hideControlsTimer;
BOOL videoShown;
VideoZoomHandler* videoZoomHandler;
}
@property (nonatomic, retain) IBOutlet InCallTableViewController* callTableController;
@property (nonatomic, retain) IBOutlet UITableView* callTableView;
@property (nonatomic, retain) IBOutlet UIView* videoGroup;
@property (nonatomic, retain) IBOutlet UIView* videoView;
#ifdef TEST_VIDEO_VIEW_CHANGE
@property (nonatomic, retain) IBOutlet UIView* testVideoView;
#endif
@property (nonatomic, retain) IBOutlet UIView* videoPreview;
@property (nonatomic, retain) IBOutlet UICamSwitch* videoCameraSwitch;
@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* videoWaitingForFirstImage;
@end

View file

@ -0,0 +1,510 @@
/* InCallViewController.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <AudioToolbox/AudioToolbox.h>
#import <AddressBook/AddressBook.h>
#import <QuartzCore/CAAnimation.h>
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/EAGLDrawable.h>
#import "IncallViewController.h"
#import "UICallCell.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import "UILinphone.h"
#import "DTActionSheet.h"
#include "linphonecore.h"
const NSInteger SECURE_BUTTON_TAG=5;
@implementation InCallViewController
@synthesize callTableController;
@synthesize callTableView;
@synthesize videoGroup;
@synthesize videoView;
@synthesize videoPreview;
@synthesize videoCameraSwitch;
@synthesize videoWaitingForFirstImage;
#ifdef TEST_VIDEO_VIEW_CHANGE
@synthesize testVideoView;
#endif
#pragma mark - Lifecycle Functions
- (id)init {
self = [super initWithNibName:@"InCallViewController" bundle:[NSBundle mainBundle]];
if(self != nil) {
self->singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)];
self->videoZoomHandler = [[VideoZoomHandler alloc] init];
}
return self;
}
- (void)dealloc {
[callTableController release];
[callTableView release];
[videoGroup release];
[videoView release];
[videoPreview release];
#ifdef TEST_VIDEO_VIEW_CHANGE
[testVideoView release];
#endif
[videoCameraSwitch release];
[videoWaitingForFirstImage release];
[videoZoomHandler release];
[[PhoneMainView instance].view removeGestureRecognizer:singleFingerTap];
[singleFingerTap release];
// Remove all observer
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"InCall"
content:@"InCallViewController"
stateBar:@"UIStateBar"
stateBarEnabled:true
tabBar:@"UICallBar"
tabBarEnabled:true
fullscreen:false
landscapeMode:true
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - ViewController Functions
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
UIDevice *device = [UIDevice currentDevice];
device.proximityMonitoringEnabled = YES;
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (hideControlsTimer != nil) {
[hideControlsTimer invalidate];
hideControlsTimer = nil;
}
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[callTableController viewWillDisappear:animated];
}
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCallUpdate
object:nil];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[callTableController viewWillAppear:animated];
}
// Set observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate
object:nil];
// Update on show
LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]);
LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0;
[self callUpdate:call state:state animated:FALSE];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[callTableController viewDidAppear:animated];
}
// Set windows (warn memory leaks)
linphone_core_set_native_video_window_id([LinphoneManager getLc], (unsigned long)videoView);
linphone_core_set_native_preview_window_id([LinphoneManager getLc], (unsigned long)videoPreview);
// Enable tap
[singleFingerTap setEnabled:TRUE];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[[UIApplication sharedApplication] setIdleTimerDisabled:false];
UIDevice *device = [UIDevice currentDevice];
device.proximityMonitoringEnabled = NO;
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[callTableController viewDidDisappear:animated];
}
// Disable tap
[singleFingerTap setEnabled:FALSE];
}
- (void)viewDidLoad {
[super viewDidLoad];
[singleFingerTap setNumberOfTapsRequired:1];
[singleFingerTap setCancelsTouchesInView: FALSE];
[[PhoneMainView instance].view addGestureRecognizer:singleFingerTap];
[videoZoomHandler setup:videoGroup];
videoGroup.alpha = 0;
[videoCameraSwitch setPreview:videoPreview];
[callTableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
[callTableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4
}
- (void)viewDidUnload {
[super viewDidUnload];
[[PhoneMainView instance].view removeGestureRecognizer:singleFingerTap];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
CGRect frame = [videoPreview frame];
switch (toInterfaceOrientation) {
case UIInterfaceOrientationPortrait:
[videoPreview setTransform: CGAffineTransformMakeRotation(0)];
break;
case UIInterfaceOrientationPortraitUpsideDown:
[videoPreview setTransform: CGAffineTransformMakeRotation(M_PI)];
break;
case UIInterfaceOrientationLandscapeLeft:
[videoPreview setTransform: CGAffineTransformMakeRotation(M_PI / 2)];
break;
case UIInterfaceOrientationLandscapeRight:
[videoPreview setTransform: CGAffineTransformMakeRotation(-M_PI / 2)];
break;
default:
break;
}
[videoPreview setFrame:frame];
}
#pragma mark -
- (void)callUpdate:(LinphoneCall *)call state:(LinphoneCallState)state animated:(BOOL)animated {
LinphoneCore *lc = [LinphoneManager getLc];
// Update table
[callTableView reloadData];
// Fake call update
if(call == NULL) {
return;
}
switch (state) {
case LinphoneCallIncomingReceived:
case LinphoneCallOutgoingInit:
{
if(linphone_core_get_calls_nb(lc) > 1) {
[callTableController minimizeAll];
}
}
case LinphoneCallConnected:
case LinphoneCallStreamsRunning:
{
//check video
if (linphone_call_params_video_enabled(linphone_call_get_current_params(call))) {
[self displayVideoCall:animated];
} else {
[self displayTableCall:animated];
const LinphoneCallParams* param = linphone_call_get_current_params(call);
const LinphoneCallAppData* callAppData = linphone_call_get_user_pointer(call);
if(state == LinphoneCallStreamsRunning
&& callAppData->videoRequested
&& linphone_call_params_low_bandwidth_enabled(param)) {
//too bad video was not enabled because low bandwidth
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Low bandwidth", nil)
message:NSLocalizedString(@"Video cannot be activated because of low bandwidth condition, only audio is available", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue", nil)
otherButtonTitles:nil];
[alert show];
[alert release];
callAppData->videoRequested=FALSE; /*reset field*/
}
}
break;
}
case LinphoneCallUpdatedByRemote:
{
const LinphoneCallParams* current = linphone_call_get_current_params(call);
const LinphoneCallParams* remote = linphone_call_get_remote_params(call);
/* remote wants to add video */
if (linphone_core_video_enabled(lc) && !linphone_call_params_video_enabled(current) &&
linphone_call_params_video_enabled(remote) &&
!linphone_core_get_video_policy(lc)->automatically_accept) {
linphone_core_defer_call_update(lc, call);
[self displayAskToEnableVideoCall:call];
} else if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) {
[self displayTableCall:animated];
}
break;
}
case LinphoneCallPausing:
case LinphoneCallPaused:
case LinphoneCallPausedByRemote:
{
[self displayTableCall:animated];
break;
}
case LinphoneCallEnd:
case LinphoneCallError:
{
if(linphone_core_get_calls_nb(lc) <= 2) {
[callTableController maximizeAll];
}
break;
}
default:
break;
}
}
- (void)showControls:(id)sender {
if (hideControlsTimer) {
[hideControlsTimer invalidate];
hideControlsTimer = nil;
}
if([[[PhoneMainView instance] currentView] equal:[InCallViewController compositeViewDescription]] && videoShown) {
// show controls
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
[[PhoneMainView instance] showTabBar: true];
[[PhoneMainView instance] showStateBar: true];
[videoCameraSwitch setAlpha:1.0];
[UIView commitAnimations];
// hide controls in 5 sec
hideControlsTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(hideControls:)
userInfo:nil
repeats:NO];
}
}
- (void)hideControls:(id)sender {
if (hideControlsTimer) {
[hideControlsTimer invalidate];
hideControlsTimer = nil;
}
if([[[PhoneMainView instance] currentView] equal:[InCallViewController compositeViewDescription]] && videoShown) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
[videoCameraSwitch setAlpha:0.0];
[UIView commitAnimations];
[[PhoneMainView instance] showTabBar: false];
[[PhoneMainView instance] showStateBar: false];
}
}
#ifdef TEST_VIDEO_VIEW_CHANGE
// Define TEST_VIDEO_VIEW_CHANGE in IncallViewController.h to enable video view switching testing
- (void)_debugChangeVideoView {
static bool normalView = false;
if (normalView) {
linphone_core_set_native_video_window_id([LinphoneManager getLc], (unsigned long)videoView);
} else {
linphone_core_set_native_video_window_id([LinphoneManager getLc], (unsigned long)testVideoView);
}
normalView = !normalView;
}
#endif
- (void)enableVideoDisplay:(BOOL)animation {
if(videoShown && animation)
return;
videoShown = true;
[videoZoomHandler resetZoom];
if(animation) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
}
[videoGroup setAlpha:1.0];
[callTableView setAlpha:0.0];
if(animation) {
[UIView commitAnimations];
}
if(linphone_core_self_view_enabled([LinphoneManager getLc])) {
[videoPreview setHidden:FALSE];
} else {
[videoPreview setHidden:TRUE];
}
if ([LinphoneManager instance].frontCamId != nil) {
// only show camera switch button if we have more than 1 camera
[videoCameraSwitch setHidden:FALSE];
}
[videoCameraSwitch setAlpha:0.0];
[[PhoneMainView instance] fullScreen: true];
[[PhoneMainView instance] showTabBar: false];
[[PhoneMainView instance] showStateBar: false];
#ifdef TEST_VIDEO_VIEW_CHANGE
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(_debugChangeVideoView) userInfo:nil repeats:YES];
#endif
// [self batteryLevelChanged:nil];
[videoWaitingForFirstImage setHidden: NO];
[videoWaitingForFirstImage startAnimating];
LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]);
//linphone_call_params_get_used_video_codec return 0 if no video stream enabled
if (call != NULL && linphone_call_params_get_used_video_codec(linphone_call_get_current_params(call))) {
linphone_call_set_next_video_frame_decoded_callback(call, hideSpinner, self);
}
}
- (void)disableVideoDisplay:(BOOL)animation {
if(!videoShown && animation)
return;
videoShown = false;
if(animation) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
}
[videoGroup setAlpha:0.0];
[[PhoneMainView instance] showTabBar: true];
[callTableView setAlpha:1.0];
[videoCameraSwitch setHidden:TRUE];
if(animation) {
[UIView commitAnimations];
}
if (hideControlsTimer != nil) {
[hideControlsTimer invalidate];
hideControlsTimer = nil;
}
[[PhoneMainView instance] fullScreen:false];
}
- (void)displayVideoCall:(BOOL)animated {
[self enableVideoDisplay:animated];
}
- (void)displayTableCall:(BOOL)animated {
[self disableVideoDisplay:animated];
}
#pragma mark - Spinner Functions
- (void)hideSpinnerIndicator: (LinphoneCall*)call {
videoWaitingForFirstImage.hidden = TRUE;
}
static void hideSpinner(LinphoneCall* call, void* user_data) {
InCallViewController* thiz = (InCallViewController*) user_data;
[thiz hideSpinnerIndicator:call];
}
#pragma mark - Event Functions
- (void)callUpdateEvent: (NSNotification*) notif {
LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue];
LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue];
[self callUpdate:call state:state animated:TRUE];
}
#pragma mark - ActionSheet Functions
- (void)displayAskToEnableVideoCall:(LinphoneCall*) call {
if (linphone_core_get_video_policy([LinphoneManager getLc])->automatically_accept)
return;
const char* lUserNameChars = linphone_address_get_username(linphone_call_get_remote_address(call));
NSString* lUserName = lUserNameChars?[[[NSString alloc] initWithUTF8String:lUserNameChars] autorelease]:NSLocalizedString(@"Unknown",nil);
const char* lDisplayNameChars = linphone_address_get_display_name(linphone_call_get_remote_address(call));
NSString* lDisplayName = [lDisplayNameChars?[[NSString alloc] initWithUTF8String:lDisplayNameChars]:@"" autorelease];
NSString* title = [NSString stringWithFormat : NSLocalizedString(@"'%@' would like to enable video",nil), ([lDisplayName length] > 0)?lDisplayName:lUserName];
DTActionSheet *sheet = [[[DTActionSheet alloc] initWithTitle:title] autorelease];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(dismissVideoActionSheet:) userInfo:sheet repeats:NO];
[sheet addButtonWithTitle:NSLocalizedString(@"Accept", nil) block:^() {
[LinphoneLogger logc:LinphoneLoggerLog format:"User accept video proposal"];
LinphoneCallParams* paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call));
linphone_call_params_enable_video(paramsCopy, TRUE);
linphone_core_accept_call_update([LinphoneManager getLc], call, paramsCopy);
linphone_call_params_destroy(paramsCopy);
[timer invalidate];
}];
[sheet addDestructiveButtonWithTitle:NSLocalizedString(@"Decline", nil) block:^() {
[LinphoneLogger logc:LinphoneLoggerLog format:"User declined video proposal"];
LinphoneCallParams* paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call));
linphone_core_accept_call_update([LinphoneManager getLc], call, paramsCopy);
linphone_call_params_destroy(paramsCopy);
[timer invalidate];
}];
[sheet showInView:[PhoneMainView instance].view];
}
- (void)dismissVideoActionSheet:(NSTimer*)timer {
DTActionSheet *sheet = (DTActionSheet *)timer.userInfo;
[sheet dismissWithClickedButtonIndex:sheet.destructiveButtonIndex animated:TRUE];
}
@end

View file

@ -1,151 +0,0 @@
/* IncallViewController.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "linphonecore.h"
#import "PhoneViewController.h"
#import "ConferenceCallDetailView.h"
#import <AddressBookUI/ABPeoplePickerNavigationController.h>
#include "UILinphone.h"
#import "UIToggleVideoButton.h"
#import "VideoZoomHandler.h"
@class VideoViewController;
@interface IncallViewController : UIViewController <ABPeoplePickerNavigationControllerDelegate,LinphoneUICallDelegate, UITableViewDelegate, UITableViewDataSource, UIActionSheetCustomDelegate> {
UIView* controlSubView, *hangUpView;
UIButton* endCtrl;
UIButton* dialer;
UIMuteButton* mute;
UIButton* pause;
UISpeakerButton* speaker;
UIButton* contacts;
UIToggleVideoButton* addVideo;
UITableView* callTableView;
UIButton* addCall, *mergeCalls;
UIButton* transfer;
//key pad
UIView* padSubView;
UIDigitButton* one;
UIDigitButton* two;
UIDigitButton* three;
UIDigitButton* four;
UIDigitButton* five;
UIDigitButton* six;
UIDigitButton* seven;
UIDigitButton* eight;
UIDigitButton* nine;
UIDigitButton* star;
UIDigitButton* zero;
UIDigitButton* hash;
UIButton* close;
UIView* videoGroup;
UIView* videoView;
UIView* videoPreview;
#ifdef TEST_VIDEO_VIEW_CHANGE
UIView* testVideoView;
#endif
UIImageView* videoCallQuality;
UICamSwitch* videoCameraSwitch;
UIActivityIndicatorView* videoUpdateIndicator;
UIActivityIndicatorView* videoWaitingForFirstImage;
bool dismissed;
NSTimer *durationRefreasher;
NSTimer * glowingTimer;
float glow;
NSIndexPath* activePath;
ABPeoplePickerNavigationController* myPeoplePickerController;
UITableViewCell* activeCallCell;
VideoViewController* mVideoViewController;
ConferenceCallDetailView* conferenceDetail;
BOOL mVideoShown;
BOOL mVideoIsPending;
BOOL mIncallViewIsReady;
UIImage* verified, *unverified;
UIImage* stat_sys_signal_0, *stat_sys_signal_1, *stat_sys_signal_2, *stat_sys_signal_3, *stat_sys_signal_4;
UIActionSheet* visibleActionSheet;
NSTimer* hideControlsTimer;
VideoZoomHandler* videoZoomHandler;
}
-(void)displayStatus:(NSString*) message;
- (IBAction)doAction:(id)sender;
+(LinphoneCall*) retrieveCallAtIndex: (NSInteger) index inConference:(bool) conf;
+ (void) updateCellImageView:(UIImageView*)imageView Label:(UILabel*)label DetailLabel:(UILabel*)detailLabel AndAccessoryView:(UIView*)accessoryView withCall:(LinphoneCall*) call;
+(void) updateIndicator:(UIImageView*) indicator withCallQuality:(float) quality;
@property (nonatomic, retain) IBOutlet UIView* controlSubView;
@property (nonatomic, retain) IBOutlet UIView* padSubView;
@property (nonatomic, retain) IBOutlet UIView* hangUpView;
@property (nonatomic, retain) IBOutlet UIViewController* conferenceDetail;
@property (nonatomic, retain) IBOutlet UIButton* endCtrl;
@property (nonatomic, retain) IBOutlet UIButton* dialer;
@property (nonatomic, retain) IBOutlet UIButton* mute;
@property (nonatomic, retain) IBOutlet UIButton* pause;
@property (nonatomic, retain) IBOutlet UIButton* speaker;
@property (nonatomic, retain) IBOutlet UIButton* contacts;
@property (nonatomic, retain) IBOutlet UIToggleVideoButton* addVideo;
@property (nonatomic, retain) IBOutlet UITableView* callTableView;
@property (nonatomic, retain) IBOutlet UIButton* addCall;
@property (nonatomic, retain) IBOutlet UIButton* mergeCalls;
@property (nonatomic, retain) IBOutlet UIButton* transfer;
@property (nonatomic, retain) IBOutlet UIButton* one;
@property (nonatomic, retain) IBOutlet UIButton* two;
@property (nonatomic, retain) IBOutlet UIButton* three;
@property (nonatomic, retain) IBOutlet UIButton* four;
@property (nonatomic, retain) IBOutlet UIButton* five;
@property (nonatomic, retain) IBOutlet UIButton* six;
@property (nonatomic, retain) IBOutlet UIButton* seven;
@property (nonatomic, retain) IBOutlet UIButton* eight;
@property (nonatomic, retain) IBOutlet UIButton* nine;
@property (nonatomic, retain) IBOutlet UIButton* star;
@property (nonatomic, retain) IBOutlet UIButton* zero;
@property (nonatomic, retain) IBOutlet UIButton* hash;
@property (nonatomic, retain) IBOutlet UIButton* close;
@property (nonatomic, retain) IBOutlet VideoViewController* videoViewController;
@property (nonatomic, retain) IBOutlet UIView* videoGroup;
@property (nonatomic, retain) IBOutlet UIView* videoView;
#ifdef TEST_VIDEO_VIEW_CHANGE
@property (nonatomic, retain) IBOutlet UIView* testVideoView;
#endif
@property (nonatomic, retain) IBOutlet UIView* videoPreview;
@property (nonatomic, retain) IBOutlet UIImageView* videoCallQuality;
@property (nonatomic, retain) IBOutlet UICamSwitch* videoCameraSwitch;
@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* videoUpdateIndicator;
@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* videoWaitingForFirstImage;
@end

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,45 @@
/* IncomingCallViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UICompositeViewController.h"
#import "TPMultiLayoutViewController.h"
#include "linphonecore.h"
@protocol IncomingCallViewDelegate <NSObject>
- (void)incomingCallAccepted:(LinphoneCall*)call;
- (void)incomingCallDeclined:(LinphoneCall*)call;
- (void)incomingCallAborted:(LinphoneCall*)call;
@end
@interface IncomingCallViewController : TPMultiLayoutViewController <UICompositeViewDelegate> {
}
@property (nonatomic, retain) IBOutlet UILabel* addressLabel;
@property (nonatomic, retain) IBOutlet UIImageView* avatarImage;
@property (nonatomic, assign) LinphoneCall* call;
@property (nonatomic, retain) id<IncomingCallViewDelegate> delegate;
- (IBAction)onAcceptClick:(id) event;
- (IBAction)onDeclineClick:(id) event;
@end

View file

@ -0,0 +1,210 @@
/* IncomingCallViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "IncomingCallViewController.h"
#import "LinphoneManager.h"
#import "FastAddressBook.h"
#import "PhoneMainView.h"
#import "UILinphone.h"
@implementation IncomingCallViewController
@synthesize addressLabel;
@synthesize avatarImage;
@synthesize call;
@synthesize delegate;
#pragma mark - Lifecycle Functions
- (id)init {
return [super initWithNibName:@"IncomingCallViewController" bundle:[NSBundle mainBundle]];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[avatarImage release];
[addressLabel release];
[delegate release];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCallUpdate
object:nil];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"IncomingCall"
content:@"IncomingCallViewController"
stateBar:nil
stateBarEnabled:false
tabBar:nil
tabBarEnabled:false
fullscreen:false
landscapeMode:[LinphoneManager runningOnIpad]
portraitMode:true];
}
return compositeDescription;
}
#pragma mark - Event Functions
- (void)callUpdateEvent:(NSNotification*)notif {
LinphoneCall *acall = [[notif.userInfo objectForKey: @"call"] pointerValue];
LinphoneCallState astate = [[notif.userInfo objectForKey: @"state"] intValue];
[self callUpdate:acall state:astate];
}
#pragma mark -
- (void)callUpdate:(LinphoneCall *)acall state:(LinphoneCallState)astate {
if(call == acall && (astate == LinphoneCallEnd || astate == LinphoneCallError)) {
[delegate incomingCallAborted:call];
[self dismiss];
}
}
- (void)dismiss {
if([[[PhoneMainView instance] currentView] equal:[IncomingCallViewController compositeViewDescription]]) {
[[PhoneMainView instance] popCurrentView];
}
}
- (void)update {
[self view]; //Force view load
[avatarImage setImage:[UIImage imageNamed:@"avatar_unknown.png"]];
NSString* address = nil;
const LinphoneAddress* addr = linphone_call_get_remote_address(call);
if (addr != NULL) {
BOOL useLinphoneAddress = true;
// contact name
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress) {
NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]];
ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress];
if(contact) {
UIImage *tmpImage = [FastAddressBook getContactImage:contact thumbnail:false];
if(tmpImage != nil) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) {
UIImage *tmpImage2 = [UIImage decodedImageWithImage:tmpImage];
dispatch_async(dispatch_get_main_queue(), ^{
avatarImage.image = tmpImage2;
});
});
}
address = [FastAddressBook getContactDisplayName:contact];
useLinphoneAddress = false;
}
ms_free(lAddress);
}
if(useLinphoneAddress) {
const char* lDisplayName = linphone_address_get_display_name(addr);
const char* lUserName = linphone_address_get_username(addr);
if (lDisplayName)
address = [NSString stringWithUTF8String:lDisplayName];
else if(lUserName)
address = [NSString stringWithUTF8String:lUserName];
}
}
// Set Address
if(address == nil) {
address = @"Unknown";
}
[addressLabel setText:address];
}
#pragma mark - Property Functions
- (void)setCall:(LinphoneCall*)acall {
call = acall;
[self update];
[self callUpdate:call state:linphone_call_get_state(call)];
}
#pragma mark - Action Functions
- (IBAction)onAcceptClick:(id)event {
[self dismiss];
[delegate incomingCallAccepted:call];
}
- (IBAction)onDeclineClick:(id)event {
[self dismiss];
[delegate incomingCallDeclined:call];
}
#pragma mark - TPMultiLayoutViewController Functions
- (NSDictionary*)attributesForView:(UIView*)view {
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
[attributes setObject:[NSValue valueWithCGRect:view.frame] forKey:@"frame"];
[attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"];
if([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
[LinphoneUtils buttonMultiViewAddAttributes:attributes button:button];
}
[attributes setObject:[NSNumber numberWithInteger:view.autoresizingMask] forKey:@"autoresizingMask"];
return attributes;
}
- (void)applyAttributes:(NSDictionary*)attributes toView:(UIView*)view {
view.frame = [[attributes objectForKey:@"frame"] CGRectValue];
view.bounds = [[attributes objectForKey:@"bounds"] CGRectValue];
if([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
[LinphoneUtils buttonMultiViewApplyAttributes:attributes button:button];
}
view.autoresizingMask = [[attributes objectForKey:@"autoresizingMask"] integerValue];
}
@end

243
Classes/LinphoneApp.xib Normal file
View file

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1181</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUIWindow</string>
<string>IBUICustomObject</string>
<string>IBUIViewController</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="590933970">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUICustomObject" id="465836664">
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIWindow" id="380026005">
<reference key="NSNextResponder"/>
<int key="NSvFlags">1325</int>
<object class="NSPSMatrix" key="NSFrameMatrix"/>
<string key="NSFrameSize">{320, 480}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIVisibleAtLaunch">YES</bool>
<bool key="IBUIResizesToFullScreen">YES</bool>
</object>
<object class="IBUIViewController" id="110348778">
<bool key="IBUIAutoresizesArchivedViewToFullSize">NO</bool>
<string key="IBUINibName">PhoneMainView</string>
<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
<int key="IBUIInterfaceOrientation">1</int>
<int key="interfaceOrientation">1</int>
</object>
<bool key="IBUIWantsFullScreenLayout">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIHorizontal">NO</bool>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="465836664"/>
</object>
<int key="connectionID">6</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">rootViewController</string>
<reference key="source" ref="380026005"/>
<reference key="destination" ref="110348778"/>
</object>
<int key="connectionID">10</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="380026005"/>
<reference key="parent" ref="0"/>
<string key="objectName">LinphoneWindow</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="590933970"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="465836664"/>
<reference key="parent" ref="0"/>
<string key="objectName">LinphoneAppDelegate</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">9</int>
<reference key="object" ref="110348778"/>
<reference key="parent" ref="0"/>
<string key="objectName">PhoneMainView</string>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">UIApplication</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="2.CustomClassName">UILinphoneWindow</string>
<dictionary class="NSMutableDictionary" key="2.IBAttributePlaceholdersKey"/>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.CustomClassName">LinphoneAppDelegate</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="9.CustomClassName">PhoneMainView</string>
<string key="9.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">16</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">LinphoneAppDelegate</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/LinphoneAppDelegate.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PhoneMainView</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">mainViewController</string>
<string key="NS.object.0">UICompositeViewController</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">mainViewController</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">mainViewController</string>
<string key="candidateClassName">UICompositeViewController</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/PhoneMainView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">TPMultiLayoutViewController</string>
<string key="superclassName">UIViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="landscapeView">UIView</string>
<string key="portraitView">UIView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="landscapeView">
<string key="name">landscapeView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo" key="portraitView">
<string key="name">portraitView</string>
<string key="candidateClassName">UIView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/TPMultiLayoutViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UICompositeViewController</string>
<string key="superclassName">TPMultiLayoutViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="contentView">UIView</string>
<string key="stateBarView">UIView</string>
<string key="tabBarView">UIView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="contentView">
<string key="name">contentView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo" key="stateBarView">
<string key="name">stateBarView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo" key="tabBarView">
<string key="name">tabBarView</string>
<string key="candidateClassName">UIView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UICompositeViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UILinphoneWindow</string>
<string key="superclassName">UIWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UILinphoneWindow.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1181</string>
</data>
</archive>

View file

@ -1,4 +1,4 @@
/* linphoneAppDelegate.h
/* LinphoneAppDelegate.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
@ -17,40 +17,27 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import <AddressBookUI/ABPeoplePickerNavigationController.h>
#define DIALER_TAB_INDEX 1
#define CONTACTS_TAB_INDEX 2
#define HISTORY_TAB_INDEX 0
#define MORE_TAB_INDEX 3
@class ContactPickerDelegate;
@class IncallViewController;
@class PhoneViewController;
@class CallHistoryTableViewController;
@interface linphoneAppDelegate : NSObject <UIApplicationDelegate,UIAlertViewDelegate> {
UIWindow *window;
IBOutlet UITabBarController* myTabBarController;
IBOutlet ABPeoplePickerNavigationController* myPeoplePickerController;
IBOutlet PhoneViewController* myPhoneViewController;
CallHistoryTableViewController* myCallHistoryTableViewController;
ContactPickerDelegate* myContactPickerDelegate;
}
- (void) loadDefaultSettings:(NSDictionary *) appDefaults;
-(void) setupUI;
-(void) startApplication;
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController* myTabBarController;
@property (nonatomic, retain) ABPeoplePickerNavigationController* myPeoplePickerController;
@property (nonatomic, retain) IBOutlet PhoneViewController* myPhoneViewController;
#import "LinphoneCoreSettingsStore.h"
@interface UILinphoneWindow : UIWindow
@end
@interface LinphoneAppDelegate : NSObject <UIApplicationDelegate,UIAlertViewDelegate> {
@private
UIWindow *window;
BOOL started;
int savedMaxCall;
}
- (void)processRemoteNotification:(NSDictionary*)userInfo;
@property (assign) BOOL started;
@end

View file

@ -1,4 +1,4 @@
/* linphoneAppDelegate.m
/* LinphoneAppDelegate.m
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
*
@ -17,223 +17,229 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "PhoneViewController.h"
#import "PhoneMainView.h"
#import "linphoneAppDelegate.h"
#import "ContactPickerDelegate.h"
#import "AddressBook/ABPerson.h"
#import "CoreTelephony/CTCallCenter.h"
#import "CoreTelephony/CTCall.h"
#import "ConsoleViewController.h"
#import "MoreViewController.h"
#include "CallHistoryTableViewController.h"
#import "LinphoneCoreSettingsStore.h"
#include "LinphoneManager.h"
#include "linphonecore.h"
#if __clang__ && __arm__
extern int __divsi3(int a, int b);
int __aeabi_idiv(int a, int b) {
return __divsi3(a,b);
@implementation UILinphoneWindow
@end
@implementation LinphoneAppDelegate
@synthesize started;
#pragma mark - Lifecycle Functions
- (id)init {
self = [super init];
if(self != nil) {
self->started = FALSE;
}
return self;
}
#endif
@implementation linphoneAppDelegate
- (void)dealloc {
[super dealloc];
}
@synthesize window;
@synthesize myTabBarController;
@synthesize myPeoplePickerController;
@synthesize myPhoneViewController;
-(void)applicationWillResignActive:(UIApplication *)application {
#pragma mark -
- (void)applicationDidEnterBackground:(UIApplication *)application{
[LinphoneLogger logc:LinphoneLoggerLog format:"applicationDidEnterBackground"];
if(![LinphoneManager isLcReady]) return;
[[LinphoneManager instance] enterBackgroundMode];
}
- (void)applicationWillResignActive:(UIApplication *)application {
[LinphoneLogger logc:LinphoneLoggerLog format:"applicationWillResignActive"];
if(![LinphoneManager isLcReady]) return;
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* call = linphone_core_get_current_call(lc);
if (call == NULL)
return;
if (call){
/* save call context */
LinphoneManager* instance = [LinphoneManager instance];
instance->currentCallContextBeforeGoingBackground.call = call;
instance->currentCallContextBeforeGoingBackground.cameraIsEnabled = linphone_call_camera_enabled(call);
/* save call context */
LinphoneManager* instance = [LinphoneManager instance];
instance->currentCallContextBeforeGoingBackground.call = call;
instance->currentCallContextBeforeGoingBackground.cameraIsEnabled = linphone_call_camera_enabled(call);
const LinphoneCallParams* params = linphone_call_get_current_params(call);
if (linphone_call_params_video_enabled(params)) {
linphone_call_enable_camera(call, false);
}
}
const LinphoneCallParams* params = linphone_call_get_current_params(call);
if (linphone_call_params_video_enabled(params)) {
linphone_call_enable_camera(call, false);
if (![[LinphoneManager instance] resignActive]) {
}
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
if (![[LinphoneManager instance] enterBackgroundMode]) {
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState == UIApplicationStateBackground
&& [[NSUserDefaults standardUserDefaults] boolForKey:@"disable_autoboot_preference"]) {
// autoboot disabled, doing nothing
return;
} else if ([LinphoneManager instance] == nil) {
[self startApplication];
}
[LinphoneLogger logc:LinphoneLoggerLog format:"applicationDidBecomeActive"];
[self startApplication];
[[LinphoneManager instance] becomeActive];
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* call = linphone_core_get_current_call(lc);
if (call == NULL)
return;
LinphoneManager* instance = [LinphoneManager instance];
if (call == instance->currentCallContextBeforeGoingBackground.call) {
const LinphoneCallParams* params = linphone_call_get_current_params(call);
if (linphone_call_params_video_enabled(params)) {
linphone_call_enable_camera(
if (call){
LinphoneManager* instance = [LinphoneManager instance];
if (call == instance->currentCallContextBeforeGoingBackground.call) {
const LinphoneCallParams* params = linphone_call_get_current_params(call);
if (linphone_call_params_video_enabled(params)) {
linphone_call_enable_camera(
call,
instance->currentCallContextBeforeGoingBackground.cameraIsEnabled);
}
instance->currentCallContextBeforeGoingBackground.call = 0;
[myPhoneViewController displayCall:call InProgressFromUI:nil forUser:nil withDisplayName:nil];
}
}
instance->currentCallContextBeforeGoingBackground.call = 0;
}
}
}
- (void) loadDefaultSettings:(NSDictionary *) appDefaults {
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound |UIRemoteNotificationTypeBadge];
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] synchronize];
}
-(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
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];
[window addSubview:myTabBarController.view];
[window makeKeyAndVisible];
[[LinphoneManager instance] setCallDelegate:myPhoneViewController];
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
}
- (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
//work around until we can access lpconfig without linphonecore
NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
@"YES", @"start_at_boot_preference",
@"YES", @"backgroundmode_preference",
#ifdef DEBUG
@"YES",@"debugenable_preference",
#else
@"NO",@"debugenable_preference",
#endif
#ifdef HAVE_G729
@"YES",@"g729_preference", // enable amr by default if compiled with
#endif
//@"+33",@"countrycode_preference",
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState == UIApplicationStateBackground
&& (![[NSUserDefaults standardUserDefaults] boolForKey:@"start_at_boot_preference"] ||
![[NSUserDefaults standardUserDefaults] boolForKey:@"backgroundmode_preference"])) {
// autoboot disabled, doing nothing
return YES;
}
[self loadDefaultSettings: appDefaults];
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState == UIApplicationStateBackground
&& [[NSUserDefaults standardUserDefaults] boolForKey:@"disable_autoboot_preference"]) {
// autoboot disabled, doing nothing
} else {
[self startApplication];
}
[self startApplication];
NSDictionary *remoteNotif =[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotif){
[LinphoneLogger log:LinphoneLoggerLog format:@"PushNotification from launch received."];
[self processRemoteNotification:remoteNotif];
}
return YES;
}
-(void) startApplication {
/* explicitely instanciate LinphoneManager */
LinphoneManager* lm = [[LinphoneManager alloc] init];
assert(lm == [LinphoneManager instance]);
[self setupUI];
[[LinphoneManager instance] startLibLinphone];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound];
- (void)startApplication {
// Restart Linphone Core if needed
if(![LinphoneManager isLcReady]) {
[[LinphoneManager instance] startLibLinphone];
}
if([LinphoneManager isLcReady]) {
// Only execute one time at application start
if(!started) {
started = TRUE;
[[PhoneMainView instance] startUp];
}
}
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
- (void)dealloc {
[window release];
[myPeoplePickerController release];
[super dealloc];
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
[self startApplication];
if([LinphoneManager isLcReady]) {
if([[url scheme] isEqualToString:@"sip"]) {
// Go to ChatRoom view
DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
if(controller != nil) {
[controller setAddress:[url absoluteString]];
}
}
}
return YES;
}
- (void)processRemoteNotification:(NSDictionary*)userInfo{
NSDictionary *aps = [userInfo objectForKey:@"aps"];
if(aps != nil) {
NSDictionary *alert = [aps objectForKey:@"alert"];
if(alert != nil) {
NSString *loc_key = [alert objectForKey:@"loc-key"];
/*if we receive a remote notification, it is because our TCP background socket was no more working.
As a result, break it and refresh registers in order to make sure to receive incoming INVITE or MESSAGE*/
LinphoneCore *lc = [LinphoneManager getLc];
linphone_core_set_network_reachable(lc, FALSE);
linphone_core_set_network_reachable(lc, TRUE);
if(loc_key != nil) {
if([loc_key isEqualToString:@"IM_MSG"]) {
[[PhoneMainView instance] addInhibitedEvent:kLinphoneTextReceived];
[[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]];
} else if([loc_key isEqualToString:@"IC_MSG"]) {
//it's a call
NSString *callid=[userInfo objectForKey:@"call-id"];
if (callid)
[[LinphoneManager instance] enableAutoAnswerForCallId:callid];
else
[LinphoneLogger log:LinphoneLoggerError format:@"PushNotification: does not have call-id yet, fix it !"];
}
}
}
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[LinphoneLogger log:LinphoneLoggerLog format:@"PushNotification: Receive %@", userInfo];
[self processRemoteNotification:userInfo];
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
LinphoneCall* call;
[(NSData*)([notification.userInfo objectForKey:@"call"]) getBytes:&call];
if (!call) {
ms_warning("Local notification received with nil call");
return;
if([notification.userInfo objectForKey:@"callId"] != nil) {
[[LinphoneManager instance] acceptCallForCallId:[notification.userInfo objectForKey:@"callId"]];
} else if([notification.userInfo objectForKey:@"chat"] != nil) {
NSString *remoteContact = (NSString*)[notification.userInfo objectForKey:@"chat"];
// Go to ChatRoom view
[[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]];
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
if(controller != nil) {
[controller setRemoteAddress:remoteContact];
}
}
linphone_core_accept_call([LinphoneManager getLc], call);
}
#pragma mark - PushNotification Functions
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
[LinphoneLogger log:LinphoneLoggerLog format:@"PushNotification: Token %@", deviceToken];
[[LinphoneManager instance] setPushNotificationToken:deviceToken];
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
[LinphoneLogger log:LinphoneLoggerError format:@"PushNotification: Error %@", [error localizedDescription]];
[[LinphoneManager instance] setPushNotificationToken:nil];
}
@end

View file

@ -1,6 +1,6 @@
/* ContactPickerDelegate.h
/* LinphoneCoreSettingsStore.h
*
* Copyright (C) 2009 Belledonne Comunications, Grenoble, France
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,16 +15,20 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
*/
#import <Foundation/Foundation.h>
#import <AddressBookUI/ABPeoplePickerNavigationController.h>
#import "PhoneViewController.h"
#import "linphoneAppDelegate.h"
#import "IASKSettingsStore.h"
#import "LinphoneManager.h"
@interface ContactPickerDelegate : NSObject<ABPeoplePickerNavigationControllerDelegate> {
@interface LinphoneCoreSettingsStore : IASKAbstractSettingsStore {
@private
NSDictionary *dict;
NSDictionary *changedDict;
}
- (void)synchronizeAccount;
- (void)transformLinphoneCoreToKeys;
@end

View file

@ -0,0 +1,678 @@
/* LinphoneCoreSettingsStore.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "LinphoneCoreSettingsStore.h"
#include "lpconfig.h"
extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
@implementation LinphoneCoreSettingsStore
- (id)init {
self = [super init];
if (self){
dict = [[NSMutableDictionary alloc] init];
changedDict = [[NSMutableDictionary alloc] init];
[self transformLinphoneCoreToKeys];
}
return self;
}
- (void)dealloc {
[dict release];
[changedDict release];
[super dealloc];
}
- (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];
}
- (NSString*)stringForKey:(NSString*) key {
return [self objectForKey: 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=[LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate];
if (pref){
bool_t value = linphone_core_payload_type_enabled(lc,pt);
[self setBool:value forKey: pref];
}else{
[LinphoneLogger logc:LinphoneLoggerWarning format:"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"];
[self setInteger: linphone_proxy_config_get_expires(cfg) forKey:@"expire_preference"];
[self setString: linphone_proxy_config_get_dial_prefix(cfg) forKey:@"prefix_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"];
[self setBool:linphone_proxy_config_get_dial_escape_plus(cfg) forKey:@"substitute_+_by_00_preference"];
}
} else {
[self setInteger: lp_config_get_int(linphone_core_get_config(lc),"default_values","reg_expires", 600) forKey:@"expire_preference"];
[self setObject:@"" forKey:@"username_preference"];
[self setObject:@"" forKey:@"domain_preference"];
[self setObject:@"" forKey:@"proxy_preference"];
[self setObject:@"" forKey:@"password_preference"];
[self setBool:FALSE forKey:@"outbound_proxy_preference"];
}
[self setBool:lp_config_get_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "pushnotification_preference", 0) forKey:@"pushnotification_preference"];
{
LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(lc);
if(parsed != NULL) {
[self setString: linphone_address_get_display_name(parsed) forKey:@"primary_displayname_preference"];
[self setString: linphone_address_get_username(parsed) forKey:@"primary_username_preference"];
}
linphone_address_destroy(parsed);
}
{
{
int minPort, maxPort;
linphone_core_get_audio_port_range(lc, &minPort, &maxPort);
if(minPort != maxPort)
[self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"audio_port_preference"];
else
[self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"audio_port_preference"];
}
{
int minPort, maxPort;
linphone_core_get_video_port_range(lc, &minPort, &maxPort);
if(minPort != maxPort)
[self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"video_port_preference"];
else
[self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"video_port_preference"];
}
}
{
[self setInteger: linphone_core_get_upload_bandwidth(lc) forKey:@"upload_bandwidth_preference"];
[self setInteger: linphone_core_get_download_bandwidth(lc) forKey:@"download_bandwidth_preference"];
}
{
[self setFloat:linphone_core_get_playback_gain_db(lc) forKey:@"playback_gain_preference"];
[self setFloat:linphone_core_get_mic_gain_db(lc) forKey:@"microphone_gain_preference"];
}
{
LCSipTransports tp;
const char *tname = "udp";
int port = 5060;
linphone_core_get_sip_transports(lc, &tp);
if (tp.udp_port>0) {
tname = "udp";
port = tp.udp_port;
} else if (tp.tcp_port>0) {
tname = "tcp";
port = tp.tcp_port;
} else if (tp.tls_port>0) {
tname = "tls";
port = tp.tls_port;
}
[self setString:tname forKey:@"transport_preference"];
[self setInteger:port forKey:@"port_preference"];
[self setInteger:lp_config_get_int(linphone_core_get_config(lc),"sip","sip_random_port", 1) forKey:@"random_port_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
setBool:linphone_core_get_firewall_policy(lc)==LinphonePolicyUseIce forKey:@"ice_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){
case LinphoneMediaEncryptionSRTP:
val="SRTP";
break;
case LinphoneMediaEncryptionZRTP:
val="ZRTP";
break;
default:
val="None";
}
[self setString:val forKey:@"media_encryption_preference"];
}
[self setString: lp_config_get_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "rotation_preference", "auto") forKey:@"rotation_preference"];
[self setBool: lp_config_get_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "edge_opt_preference", 0) forKey:@"edge_opt_preference"];
[self setBool: lp_config_get_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "enable_first_login_view_preference", 0) forKey:@"enable_first_login_view_preference"];
[self setBool: lp_config_get_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "debugenable_preference", 0) forKey:@"debugenable_preference"];
[self setBool: lp_config_get_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "animations_preference", 1) forKey:@"animations_preference"];
[self setBool: lp_config_get_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "wifi_only_preference", 0) forKey:@"wifi_only_preference"];
[self setString: lp_config_get_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "sharing_server_preference", NULL) forKey:@"sharing_server_preference"];
/*keep this one also in the standardUserDefaults so that it can be read before starting liblinphone*/
BOOL start_at_boot = TRUE;
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"start_at_boot_preference"] != Nil)
start_at_boot = [[NSUserDefaults standardUserDefaults] boolForKey:@"start_at_boot_preference"];
[self setBool: start_at_boot forKey:@"start_at_boot_preference"];
BOOL background_mode = TRUE;
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"backgroundmode_preference"] != Nil)
background_mode =[[NSUserDefaults standardUserDefaults] boolForKey:@"backgroundmode_preference"];
[self setBool: background_mode forKey:@"backgroundmode_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_initiate) forKey:@"start_video_preference"];
[self setBool:(pol->automatically_accept) forKey:@"accept_video_preference"];
[self setBool:linphone_core_self_view_enabled(lc) forKey:@"self_video_preference"];
[self setBool:linphone_core_video_preview_enabled(lc) forKey:@"preview_preference"];
}
{
[self setBool:linphone_core_get_use_info_for_dtmf(lc) forKey:@"sipinfo_dtmf_preference"];
[self setBool:linphone_core_get_use_rfc2833_for_dtmf(lc) forKey:@"rfc_dtmf_preference"];
[self setInteger:linphone_core_get_inc_timeout(lc) forKey:@"incoming_call_timeout_preference"];
[self setInteger:linphone_core_get_in_call_timeout(lc) forKey:@"in_call_timeout_preference"];
}
// Tunnel
if (linphone_core_tunnel_available()){
LinphoneTunnel *tunnel = linphone_core_get_tunnel([LinphoneManager getLc]);
[self setString:lp_config_get_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "tunnel_mode_preference", "off") forKey:@"tunnel_mode_preference"];
const MSList* configs = linphone_tunnel_get_servers(tunnel);
if(configs != NULL) {
LinphoneTunnelConfig *ltc = (LinphoneTunnelConfig *)configs->data;
[self setString:linphone_tunnel_config_get_host(ltc) forKey:@"tunnel_address_preference"];
[self setInteger:linphone_tunnel_config_get_port(ltc) forKey:@"tunnel_port_preference"];
} else {
[self setString:"" forKey:@"tunnel_address_preference"];
[self setInteger:443 forKey:@"tunnel_port_preference"];
}
}
[changedDict release];
changedDict = [[NSMutableDictionary alloc] init];
// Post event
NSDictionary *eventDic = [NSDictionary dictionaryWithObject:self forKey:@"settings"];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneLogsUpdate object:self userInfo:eventDic];
}
- (void)setObject:(id)value forKey:(NSString *)key {
[dict setValue:value forKey:key];
[changedDict setValue:[NSNumber numberWithBool:TRUE] forKey:key];
}
- (id)objectForKey:(NSString*)key {
return [dict valueForKey:key];
}
- (BOOL)valueChangedForKey:(NSString*)key {
return [[changedDict valueForKey:key] boolValue];
}
- (void)synchronizeAccount {
LinphoneCore *lc = [LinphoneManager getLc];
LinphoneManager* lLinphoneMgr = [LinphoneManager instance];
LinphoneProxyConfig* proxyCfg = NULL;
/* unregister before modifying any settings */
{
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"];
int port_preference = [self integerForKey:@"port_preference"];
BOOL random_port_preference = [self boolForKey:@"random_port_preference"];
lp_config_set_int(linphone_core_get_config(lc),"sip","sip_random_port", random_port_preference);
lp_config_set_int(linphone_core_get_config(lc),"sip","sip_tcp_random_port", random_port_preference);
lp_config_set_int(linphone_core_get_config(lc),"sip","sip_tls_random_port", random_port_preference);
if(random_port_preference) {
port_preference = (0xDFFF&random())+1024;
[self setInteger:port_preference forKey:@"port_preference"]; // Update back preference
}
LCSipTransports transportValue={0};
if (transport!=nil) {
if (linphone_core_get_sip_transports(lc, &transportValue)) {
[LinphoneLogger logc:LinphoneLoggerError format:"cannot get current transport"];
}
// Only one port can be set at one time, the others's value is 0
if ([transport isEqualToString:@"tcp"]) {
transportValue.tcp_port=port_preference;
transportValue.udp_port=0;
transportValue.tls_port=0;
} else if ([transport isEqualToString:@"udp"]){
transportValue.udp_port=port_preference;
transportValue.tcp_port=0;
transportValue.tls_port=0;
} else if ([transport isEqualToString:@"tls"]){
transportValue.tls_port=port_preference;
transportValue.tcp_port=0;
transportValue.udp_port=0;
} else {
[LinphoneLogger logc:LinphoneLoggerError format:"unexpected transport [%s]",[transport cStringUsingEncoding:[NSString defaultCStringEncoding]]];
}
if (linphone_core_set_sip_transports(lc, &transportValue)) {
[LinphoneLogger logc:LinphoneLoggerError format:"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 = [self 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]];
//possible valid config detected
proxyCfg = linphone_core_create_proxy_config(lc);
// 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);
int expire = [self integerForKey:@"expire_preference"];
linphone_proxy_config_expires(proxyCfg,expire);
BOOL isWifiOnly = [self boolForKey:@"wifi_only_preference"];
if (isWifiOnly && lLinphoneMgr.connectivity == wwan) {
linphone_proxy_config_expires(proxyCfg, 0);
} else {
linphone_proxy_config_expires(proxyCfg, expire);
}
if (isOutboundProxy)
linphone_proxy_config_set_route(proxyCfg, proxy);
if ([self objectForKey:@"prefix_preference"]) {
NSString* prefix = [self stringForKey:@"prefix_preference"];
if ([prefix length]>0) {
linphone_proxy_config_set_dial_prefix(proxyCfg, [prefix cStringUsingEncoding:[NSString defaultCStringEncoding]]);
}
}
if ([self objectForKey:@"substitute_+_by_00_preference"]) {
bool substitute_plus_by_00 = [self boolForKey:@"substitute_+_by_00_preference"];
linphone_proxy_config_set_dial_escape_plus(proxyCfg,substitute_plus_by_00);
}
BOOL pushnotification = [self boolForKey:@"pushnotification_preference"];
lp_config_set_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "pushnotification_preference", pushnotification);
[[LinphoneManager instance] addPushTokenToProxyConfig:proxyCfg];
linphone_core_add_proxy_config(lc,proxyCfg);
//set to default proxy
linphone_core_set_default_proxy(lc,proxyCfg);
}
[[[LinphoneManager instance] fastAddressBook] reload];
}
+ (int)validPort:(int)port {
if(port < 0) {
return 0;
}
if(port > 65535) {
return 65535;
}
return port;
}
+ (BOOL)parsePortRange:(NSString*)text minPort:(int*)minPort maxPort:(int*)maxPort {
NSError* error = nil;
*minPort = -1;
*maxPort = -1;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"([0-9]+)(([^0-9]+)([0-9]+))?" options:0 error:&error];
if(error != NULL)
return FALSE;
NSArray* matches = [regex matchesInString:text options:0 range:NSMakeRange(0, [text length])];
if([matches count] == 1) {
NSTextCheckingResult *match = [matches objectAtIndex:0];
bool range = [match rangeAtIndex:2].length > 0;
if(!range) {
NSRange rangeMinPort = [match rangeAtIndex:1];
*minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] integerValue]];
*maxPort = *minPort;
return TRUE;
} else {
NSRange rangeMinPort = [match rangeAtIndex:1];
*minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] integerValue]];
NSRange rangeMaxPort = [match rangeAtIndex:4];
*maxPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMaxPort] integerValue]];
if(*minPort > *maxPort) {
*minPort = *maxPort;
}
return TRUE;
}
}
return FALSE;
}
- (BOOL)synchronize {
if (![LinphoneManager isLcReady]) return YES;
LinphoneCore *lc=[LinphoneManager getLc];
BOOL account_changed;
account_changed=[self valueChangedForKey:@"username_preference"]
|| [self valueChangedForKey:@"password_preference"]
|| [self valueChangedForKey:@"domain_preference"]
|| [self valueChangedForKey:@"expire_preference"]
|| [self valueChangedForKey:@"proxy_preference"]
|| [self valueChangedForKey:@"outbound_proxy_preference"]
|| [self valueChangedForKey:@"transport_preference"]
|| [self valueChangedForKey:@"port_preference"]
|| [self valueChangedForKey:@"random_port_preference"]
|| [self valueChangedForKey:@"prefix_preference"]
|| [self valueChangedForKey:@"substitute_+_by_00_preference"]
|| [self valueChangedForKey:@"pushnotification_preference"];
if (account_changed)
[self synchronizeAccount];
//Configure Codecs
PayloadType *pt;
const MSList *elem;
for (elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){
pt=(PayloadType*)elem->data;
NSString *pref=[LinphoneManager getPreferenceForCodec: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;
NSString *pref=[LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate];
linphone_core_enable_payload_type(lc,pt,[self boolForKey: pref]);
}
linphone_core_set_use_info_for_dtmf(lc, [self boolForKey:@"sipinfo_dtmf_preference"]);
linphone_core_set_use_rfc2833_for_dtmf(lc, [self boolForKey:@"rfc_dtmf_preference"]);
linphone_core_set_inc_timeout(lc, [self integerForKey:@"incoming_call_timeout_preference"]);
linphone_core_set_in_call_timeout(lc, [self integerForKey:@"in_call_timeout_preference"]);
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"] == NSOrderedSame)
linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionSRTP);
else if (menc && [menc compare:@"ZRTP"] == NSOrderedSame)
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 UTF8String]);
BOOL ice_preference = [self boolForKey:@"ice_preference"];
if(ice_preference) {
linphone_core_set_firewall_policy(lc, LinphonePolicyUseIce);
} else {
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:@"accept_video_preference"];
policy.automatically_initiate = [self boolForKey:@"start_video_preference"];
linphone_core_set_video_policy(lc, &policy);
linphone_core_enable_self_view(lc, [self boolForKey:@"self_video_preference"]);
linphone_core_enable_video_preview(lc, [self boolForKey:@"preview_preference"]);
// Primary contact
NSString* displayname = [self stringForKey:@"primary_displayname_preference"];
NSString* username = [self stringForKey:@"primary_username_preference"];
LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(lc);
if(parsed != NULL) {
linphone_address_set_display_name(parsed,[displayname cStringUsingEncoding:[NSString defaultCStringEncoding]]);
linphone_address_set_username(parsed,[username cStringUsingEncoding:[NSString defaultCStringEncoding]]);
char *contact = linphone_address_as_string(parsed);
linphone_core_set_primary_contact(lc, contact);
ms_free(contact);
linphone_address_destroy(parsed);
}
// Audio & Video Port
{
NSString *audio_port_preference = [self stringForKey:@"audio_port_preference"];
int minPort, maxPort;
[LinphoneCoreSettingsStore parsePortRange:audio_port_preference minPort:&minPort maxPort:&maxPort];
linphone_core_set_audio_port_range(lc, minPort, maxPort);
}
{
NSString *video_port_preference = [self stringForKey:@"video_port_preference"];
int minPort, maxPort;
[LinphoneCoreSettingsStore parsePortRange:video_port_preference minPort:&minPort maxPort:&maxPort];
linphone_core_set_video_port_range(lc, minPort, maxPort);
}
int upload_bandwidth = [self integerForKey:@"upload_bandwidth_preference"];
linphone_core_set_upload_bandwidth(lc, upload_bandwidth);
int download_bandwidth = [self integerForKey:@"download_bandwidth_preference"];
linphone_core_set_download_bandwidth(lc, download_bandwidth);
float playback_gain = [self floatForKey:@"playback_gain_preference"];
linphone_core_set_playback_gain_db(lc, playback_gain);
float mic_gain = [self floatForKey:@"microphone_gain_preference"];
linphone_core_set_mic_gain_db(lc, mic_gain);
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), LINPHONERC_APPLICATION_KEY, "backgroundmode_preference", isbackgroundModeEnabled);
BOOL firstloginview = [self boolForKey:@"enable_first_login_view_preference"];
lp_config_set_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "enable_first_login_view_preference", firstloginview);
BOOL edgeOpt = [self boolForKey:@"edge_opt_preference"];
lp_config_set_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "edge_opt_preference", edgeOpt);
NSString *landscape = [self stringForKey:@"rotation_preference"];
lp_config_set_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "rotation_preference", [landscape UTF8String]);
BOOL debugmode = [self boolForKey:@"debugenable_preference"];
lp_config_set_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "debugenable_preference", debugmode);
if (debugmode) {
linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler);
ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
} else {
linphone_core_disable_logs();
}
[[NSUserDefaults standardUserDefaults] setBool:debugmode forKey:@"debugenable_preference"]; //to be used at linphone core startup
BOOL animations = [self boolForKey:@"animations_preference"];
lp_config_set_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "animations_preference", animations);
BOOL wifiOnly = [self boolForKey:@"wifi_only_preference"];
lp_config_set_int(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "wifi_only_preference", wifiOnly);
if([self valueChangedForKey:@"wifi_only_preference"]) {
[[LinphoneManager instance] setupNetworkReachabilityCallback];
}
NSString* sharing_server = [self stringForKey:@"sharing_server_preference"];
[[LinphoneManager instance] lpConfigSetString:sharing_server forKey:@"sharing_server_preference"];
/*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"];
BOOL background_mode = [self boolForKey:@"backgroundmode_preference"];
[[NSUserDefaults standardUserDefaults] setBool: background_mode forKey:@"backgroundmode_preference"];
//Tunnel
if (linphone_core_tunnel_available()){
NSString* lTunnelPrefMode = [self stringForKey:@"tunnel_mode_preference"];
NSString* lTunnelPrefAddress = [self stringForKey:@"tunnel_address_preference"];
int lTunnelPrefPort = [self integerForKey:@"tunnel_port_preference"];
LinphoneTunnel *tunnel = linphone_core_get_tunnel([LinphoneManager getLc]);
TunnelMode mode = tunnel_off;
int lTunnelPort = 443;
if (lTunnelPrefPort) {
lTunnelPort = lTunnelPrefPort;
}
linphone_tunnel_clean_servers(tunnel);
if (lTunnelPrefAddress && [lTunnelPrefAddress length]) {
LinphoneTunnelConfig *ltc = linphone_tunnel_config_new();
linphone_tunnel_config_set_host(ltc, [lTunnelPrefAddress UTF8String]);
linphone_tunnel_config_set_port(ltc, lTunnelPort);
linphone_tunnel_add_server(tunnel, ltc);
if ([lTunnelPrefMode isEqualToString:@"off"]) {
mode = tunnel_off;
} else if ([lTunnelPrefMode isEqualToString:@"on"]) {
mode = tunnel_on;
} else if ([lTunnelPrefMode isEqualToString:@"wwan"]) {
mode = tunnel_wwan;
} else if ([lTunnelPrefMode isEqualToString:@"auto"]) {
mode = tunnel_auto;
} else {
[LinphoneLogger logc:LinphoneLoggerError format:"Unexpected tunnel mode [%s]",[lTunnelPrefMode cStringUsingEncoding:[NSString defaultCStringEncoding]]];
}
}
lp_config_set_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "tunnel_mode_preference", [lTunnelPrefMode UTF8String]);
[[LinphoneManager instance] setTunnelMode:mode];
}
// Force synchronize
[[NSUserDefaults standardUserDefaults] synchronize];
[changedDict release];
changedDict = [[NSMutableDictionary alloc] init];
// Post event
NSDictionary *eventDic = [NSDictionary dictionaryWithObject:self forKey:@"settings"];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneSettingsUpdate object:self userInfo:eventDic];
return YES;
}
@end

177
Classes/LinphoneManager.h Normal file
View file

@ -0,0 +1,177 @@
/* LinphoneManager.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <Foundation/Foundation.h>
#import <AVFoundation/AVAudioSession.h>
#import <SystemConfiguration/SCNetworkReachability.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AssetsLibrary/ALAssetsLibrary.h>
#import <CoreTelephony/CTCallCenter.h>
#import <sqlite3.h>
#import "IASKSettingsReader.h"
#import "IASKSettingsStore.h"
#import "IASKAppSettingsViewController.h"
#import "FastAddressBook.h"
#import "Utils.h"
#include "linphonecore.h"
#include "linphone_tunnel.h"
extern const char *const LINPHONERC_APPLICATION_KEY;
extern NSString *const kLinphoneCoreUpdate;
extern NSString *const kLinphoneDisplayStatusUpdate;
extern NSString *const kLinphoneTextReceived;
extern NSString *const kLinphoneCallUpdate;
extern NSString *const kLinphoneRegistrationUpdate;
extern NSString *const kLinphoneMainViewChange;
extern NSString *const kLinphoneAddressBookUpdate;
extern NSString *const kLinphoneLogsUpdate;
extern NSString *const kLinphoneSettingsUpdate;
extern NSString *const kContactSipField;
typedef enum _NetworkType {
network_none = 0,
network_2g,
network_3g,
network_4g,
network_lte,
network_wifi
} NetworkType;
typedef enum _TunnelMode {
tunnel_off = 0,
tunnel_on,
tunnel_wwan,
tunnel_auto
} TunnelMode;
typedef enum _Connectivity {
wifi,
wwan,
none
} Connectivity;
/* Application specific call context */
typedef struct _CallContext {
LinphoneCall* call;
bool_t cameraIsEnabled;
} CallContext;
struct NetworkReachabilityContext {
bool_t testWifi, testWWan;
void (*networkStateChanged) (Connectivity newConnectivity);
};
@interface LinphoneCallAppData :NSObject {
@public
bool_t batteryWarningShown;
UILocalNotification *notification;
NSMutableDictionary *userInfos;
bool_t videoRequested; /*set when user has requested for video*/
};
@end
typedef struct _LinphoneManagerSounds {
SystemSoundID call;
SystemSoundID message;
} LinphoneManagerSounds;
@interface LinphoneManager : NSObject <AVAudioSessionDelegate> {
@protected
SCNetworkReachabilityRef proxyReachability;
@private
NSTimer* mIterateTimer;
NSMutableArray* pendindCallIdFromRemoteNotif;
Connectivity connectivity;
BOOL stopWaitingRegisters;
UIBackgroundTaskIdentifier pausedCallBgTask;
UIBackgroundTaskIdentifier incallBgTask;
CTCallCenter* mCallCenter;
@public
CallContext currentCallContextBeforeGoingBackground;
}
+ (LinphoneManager*)instance;
#ifdef DEBUG
+ (void)instanceRelease;
#endif
+ (LinphoneCore*) getLc;
+ (BOOL)isLcReady;
+ (BOOL)runningOnIpad;
+ (BOOL)isNotIphone3G;
+ (NSString *)getPreferenceForCodec: (const char*) name withRate: (int) rate;
+ (NSSet *)unsupportedCodecs;
+ (NSString *)getUserAgent;
- (void)startLibLinphone;
- (void)destroyLibLinphone;
- (BOOL)resignActive;
- (void)becomeActive;
- (BOOL)enterBackgroundMode;
- (void)enableAutoAnswerForCallId:(NSString*) callid;
- (void)addPushTokenToProxyConfig: (LinphoneProxyConfig*)cfg;
- (BOOL)shouldAutoAcceptCallForCallId:(NSString*) callId;
- (void)acceptCallForCallId:(NSString*)callid;
- (void)waitForRegisterToArrive;
+ (void)kickOffNetworkConnection;
- (void)setupNetworkReachabilityCallback;
- (void)refreshRegisters;
+ (BOOL)copyFile:(NSString*)src destination:(NSString*)dst override:(BOOL)override;
+ (NSString*)bundleFile:(NSString*)file;
+ (NSString*)documentFile:(NSString*)file;
- (void)acceptCall:(LinphoneCall *)call;
- (void)call:(NSString *)address displayName:(NSString*)displayName transfer:(BOOL)transfer;
- (void)lpConfigSetString:(NSString*)value forKey:(NSString*)key;
- (NSString*)lpConfigStringForKey:(NSString*)key;
- (void)lpConfigSetString:(NSString*)value forKey:(NSString*)key forSection:(NSString*)section;
- (NSString*)lpConfigStringForKey:(NSString*)key forSection:(NSString*)section;
- (void)lpConfigSetInt:(NSInteger)value forKey:(NSString*)key;
- (NSInteger)lpConfigIntForKey:(NSString*)key;
- (void)lpConfigSetInt:(NSInteger)value forKey:(NSString*)key forSection:(NSString*)section;
- (NSInteger)lpConfigIntForKey:(NSString*)key forSection:(NSString*)section;
- (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key;
- (BOOL)lpConfigBoolForKey:(NSString*)key;
- (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key forSection:(NSString*)section;
- (BOOL)lpConfigBoolForKey:(NSString*)key forSection:(NSString*)section;
@property (readonly) FastAddressBook* fastAddressBook;
@property Connectivity connectivity;
@property (readonly) NetworkType network;
@property (readonly) const char* frontCamId;
@property (readonly) const char* backCamId;
@property (readonly) sqlite3* database;
@property (nonatomic, retain) NSData *pushNotificationToken;
@property (readonly) LinphoneManagerSounds sounds;
@property (readonly) NSMutableArray *logs;
@property (nonatomic, assign) BOOL speakerEnabled;
@property (readonly) ALAssetsLibrary *photoLibrary;
@property (nonatomic, assign) TunnelMode tunnelMode;
@end

1463
Classes/LinphoneManager.m Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,101 +0,0 @@
/* FastAddressBook.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "FastAddressBook.h"
@implementation FastAddressBook
@synthesize addressBook;
-(Contact*) getMatchingRecord:(NSString*) number {
@synchronized (mAddressBookMap){
return (Contact*) [mAddressBookMap objectForKey:number];
}
}
+(NSString*) appendCountryCodeIfPossible:(NSString*) number {
if (![number hasPrefix:@"+"] && ![number hasPrefix:@"00"]) {
NSString* lCountryCode = [[NSUserDefaults standardUserDefaults] stringForKey:@"countrycode_preference"];
if (lCountryCode && [lCountryCode length]>0) {
//append country code
return [lCountryCode stringByAppendingString:number];
}
}
return number;
}
+(NSString*) normalizePhoneNumber:(NSString*) number {
NSString* lNormalizedNumber = [(NSString*)number stringByReplacingOccurrencesOfString:@" " withString:@""];
lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@"-" withString:@""];
lNormalizedNumber = [FastAddressBook appendCountryCodeIfPossible:lNormalizedNumber];
return lNormalizedNumber;
}
void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
NSMutableDictionary* lAddressBookMap = (NSMutableDictionary*)context;
@synchronized (lAddressBookMap) {
[lAddressBookMap removeAllObjects];
NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
for (id lPerson in lContacts) {
ABMutableMultiValueRef lPhoneNumbers = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonPhoneProperty);
for ( int i=0; i<ABMultiValueGetCount(lPhoneNumbers); i++) {
CFStringRef lValue = ABMultiValueCopyValueAtIndex(lPhoneNumbers,i);
CFStringRef lLabel = ABMultiValueCopyLabelAtIndex(lPhoneNumbers,i);
CFStringRef lLocalizedLabel = ABAddressBookCopyLocalizedLabel(lLabel);
NSString* lNormalizedKey = [FastAddressBook normalizePhoneNumber:(NSString*)lValue];
Contact* lContact = [[Contact alloc] initWithRecord:lPerson ofType:(NSString *)lLocalizedLabel];
[lAddressBookMap setObject:lContact forKey:lNormalizedKey];
CFRelease(lValue);
[lContact release];
if (lLabel) CFRelease(lLabel);
if (lLocalizedLabel) CFRelease(lLocalizedLabel);
}
CFRelease(lPhoneNumbers);
}
CFRelease(lContacts);
}
}
-(FastAddressBook*) init {
if ((self = [super init])) {
mAddressBookMap = [[NSMutableDictionary alloc] init];
addressBook = ABAddressBookCreate();
ABAddressBookRegisterExternalChangeCallback (addressBook,sync_address_book,mAddressBookMap);
sync_address_book(addressBook,nil,mAddressBookMap);
}
return self;
}
@end
@implementation Contact
@synthesize record;
@synthesize numberType;
-(id) initWithRecord:(ABRecordRef) aRecord ofType:(NSString*) type {
if ((self = [super init])) {
record=CFRetain(aRecord);
numberType= [type?type:@"unknown" retain];
}
return self;
}
- (void)dealloc {
CFRelease(record);
[numberType release];
[super dealloc];
}
@end

View file

@ -1,114 +0,0 @@
/* LinphoneManager.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <Foundation/Foundation.h>
#import <AVFoundation/AVAudioSession.h>
#import <SystemConfiguration/SCNetworkReachability.h>
#include "linphonecore.h"
#import "LogView.h"
#import "LinphoneUIDelegates.h"
#import "CoreTelephony/CTCallCenter.h"
typedef enum _Connectivity {
wifi,
wwan
,none
} Connectivity;
typedef enum _TunnelMode {
off
,on
,wwan_only
,autodetect
} TunnelMode;
@class FastAddressBook;
/* Application specific call context */
typedef struct _CallContext {
LinphoneCall* call;
bool_t cameraIsEnabled;
} CallContext;
struct NetworkReachabilityContext {
bool_t testWifi, testWWan;
void (*networkStateChanged) (Connectivity newConnectivity);
};
typedef struct _LinphoneCallAppData {
bool_t batteryWarningShown;
// transfer data
int transferButtonIndex;
} LinphoneCallAppData;
@interface LinphoneManager : NSObject <AVAudioSessionDelegate> {
@protected
SCNetworkReachabilityRef proxyReachability;
@private
NSTimer* mIterateTimer;
id<LogView> mLogView;
bool isbackgroundModeEnabled;
id<LinphoneUICallDelegate> callDelegate;
id<LinphoneUIRegistrationDelegate> registrationDelegate;
UIViewController* mCurrentViewController;
Connectivity connectivity;
FastAddressBook* mFastAddressBook;
TunnelMode tunnelMode;
const char* frontCamId;
const char* backCamId;
NSDictionary* currentSettings;
CTCallCenter* callCenter;
@public
CallContext currentCallContextBeforeGoingBackground;
}
+(LinphoneManager*) instance;
+(LinphoneCore*) getLc;
+(BOOL) runningOnIpad;
+(void) set:(UIView*)view hidden: (BOOL) hidden withName:(const char*)name andReason:(const char*) reason;
+(void) logUIElementPressed:(const char*) name;
-(void) displayDialer;
-(void) registerLogView:(id<LogView>) view;
-(void) startLibLinphone;
-(BOOL) isNotIphone3G;
-(void) destroyLibLinphone;
-(BOOL) enterBackgroundMode;
-(void) becomeActive;
-(void) kickOffNetworkConnection;
-(NSString*) getDisplayNameFromAddressBook:(NSString*) number andUpdateCallLog:(LinphoneCallLog*)log;
-(UIImage*) getImageFromAddressBook:(NSString*) number;
-(BOOL) reconfigureLinphoneIfNeeded:(NSDictionary *)oldSettings;
-(void) setupNetworkReachabilityCallback;
-(void) refreshRegisters;
@property (nonatomic, retain) id<LinphoneUICallDelegate> callDelegate;
@property (nonatomic, retain) id<LinphoneUIRegistrationDelegate> registrationDelegate;
@property Connectivity connectivity;
@property TunnelMode tunnelMode;
@property (readonly) const char* frontCamId;
@property (readonly) const char* backCamId;
@end

File diff suppressed because it is too large Load diff

View file

@ -1,43 +0,0 @@
/* LinphoneUIControler.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#include "linphonecore.h"
@protocol LinphoneUICallDelegate
// UI changes
-(void) displayDialerFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName;
-(void) displayCall: (LinphoneCall*) call InProgressFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName;
-(void) displayIncomingCall: (LinphoneCall*) call NotificationFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName;
-(void) displayInCall: (LinphoneCall*) call FromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName;
-(void) displayVideoCall:(LinphoneCall*) call FromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName;
//status reporting
-(void) displayStatus:(NSString*) message;
-(void) displayAskToEnableVideoCall:(LinphoneCall*) call forUser:(NSString*) username withDisplayName:(NSString*) displayName;
-(void) firstVideoFrameDecoded:(LinphoneCall*) call;
@end
@protocol LinphoneUIRegistrationDelegate
// UI changes for registration
-(void) displayRegisteredFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName onDomain:(NSString*)domain ;
-(void) displayRegisteringFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName onDomain:(NSString*)domain ;
-(void) displayRegistrationFailedFromUI:(UIViewController*) viewCtrl forUser:(NSString*) username withDisplayName:(NSString*) displayName onDomain:(NSString*)domain forReason:(NSString*) reason;
-(void) displayNotRegisteredFromUI:(UIViewController*) viewCtrl;
@end

View file

@ -0,0 +1,24 @@
/* UIAddressTextField.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
@interface UIAddressTextField : UITextField
@end

View file

@ -0,0 +1,29 @@
/* UIAddressTextField.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "UIAddressTextField.h"
@implementation UIAddressTextField
- (void)setText:(NSString *)text {
[super setText:text];
[self sendActionsForControlEvents:UIControlEventEditingChanged];
}
@end

View file

@ -19,13 +19,15 @@
#import "UIBluetoothButton.h"
#import <AudioToolbox/AudioToolbox.h>
#import "Utils.h"
#include "linphonecore.h"
@implementation UIBluetoothButton
#define check_auresult(au,method) \
if (au!=0) ms_error("UIBluetoothButton error for %s: ret=%ld",method,au)
if (au!=0) [LinphoneLogger logc:LinphoneLoggerError format:"UIBluetoothButton error for %s: ret=%ld",method,au]
-(void) onOn {
- (void)onOn {
//redirect audio to bluetooth
UInt32 size = sizeof(CFStringRef);
@ -42,7 +44,8 @@ if (au!=0) ms_error("UIBluetoothButton error for %s: ret=%ld",method,au)
check_auresult(result,"set kAudioSessionProperty_OverrideCategoryEnableBluetoothInput 1");
}
-(void) onOff {
- (void)onOff {
//redirect audio to bluetooth
int allowBluetoothInput = 0;
OSStatus result = AudioSessionSetProperty (
@ -58,22 +61,13 @@ if (au!=0) ms_error("UIBluetoothButton error for %s: ret=%ld",method,au)
}
-(bool) isInitialStateOn {
- (bool)onUpdate {
return false;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code.
}
*/
- (void)dealloc {
[super dealloc];
}
@end

View file

@ -0,0 +1,66 @@
/* UICallBar.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UIMicroButton.h"
#import "UIPauseButton.h"
#import "UISpeakerButton.h"
#import "UIVideoButton.h"
#import "UIHangUpButton.h"
#import "UIDigitButton.h"
#import "TPMultiLayoutViewController.h"
@interface UICallBar: TPMultiLayoutViewController {
}
@property (nonatomic, retain) IBOutlet UIPauseButton* pauseButton;
@property (nonatomic, retain) IBOutlet UIButton* conferenceButton;
@property (nonatomic, retain) IBOutlet UIVideoButton* videoButton;
@property (nonatomic, retain) IBOutlet UIMicroButton* microButton;
@property (nonatomic, retain) IBOutlet UISpeakerButton* speakerButton;
@property (nonatomic, retain) IBOutlet UIToggleButton* optionsButton;
@property (nonatomic, retain) IBOutlet UIHangUpButton* hangupButton;
@property (nonatomic, retain) IBOutlet UIView* padView;
@property (nonatomic, retain) IBOutlet UIView* optionsView;
@property (nonatomic, retain) IBOutlet UIButton* optionsAddButton;
@property (nonatomic, retain) IBOutlet UIButton* optionsTransferButton;
@property (nonatomic, retain) IBOutlet UIToggleButton* dialerButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* oneButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* twoButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* threeButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* fourButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* fiveButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* sixButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* sevenButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* eightButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* nineButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* starButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* zeroButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* sharpButton;
- (IBAction)onOptionsClick:(id)sender;
- (IBAction)onOptionsTransferClick:(id)sender;
- (IBAction)onOptionsAddClick:(id)sender;
- (IBAction)onConferenceClick:(id)sender;
- (IBAction)onPadClick:(id)sender;
@end

View file

@ -0,0 +1,481 @@
/* UICallBar.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "UICallBar.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import "Utils.h"
#import "CAAnimation+Blocks.h"
#include "linphonecore.h"
@implementation UICallBar
@synthesize pauseButton;
@synthesize conferenceButton;
@synthesize videoButton;
@synthesize microButton;
@synthesize speakerButton;
@synthesize optionsButton;
@synthesize hangupButton;
@synthesize optionsAddButton;
@synthesize optionsTransferButton;
@synthesize dialerButton;
@synthesize padView;
@synthesize optionsView;
@synthesize oneButton;
@synthesize twoButton;
@synthesize threeButton;
@synthesize fourButton;
@synthesize fiveButton;
@synthesize sixButton;
@synthesize sevenButton;
@synthesize eightButton;
@synthesize nineButton;
@synthesize starButton;
@synthesize zeroButton;
@synthesize sharpButton;
#pragma mark - Lifecycle Functions
- (id)init {
return [super initWithNibName:@"UICallBar" bundle:[NSBundle mainBundle]];
}
- (void)dealloc {
[pauseButton release];
[conferenceButton release];
[videoButton release];
[microButton release];
[speakerButton release];
[optionsButton release];
[optionsAddButton release];
[optionsTransferButton release];
[dialerButton release];
[oneButton release];
[twoButton release];
[threeButton release];
[fourButton release];
[fiveButton release];
[sixButton release];
[sevenButton release];
[eightButton release];
[nineButton release];
[starButton release];
[zeroButton release];
[sharpButton release];
[padView release];
[optionsView release];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[pauseButton setType:UIPauseButtonType_CurrentCall call:nil];
[zeroButton setDigit:'0'];
[zeroButton setDtmf:true];
[oneButton setDigit:'1'];
[oneButton setDtmf:true];
[twoButton setDigit:'2'];
[twoButton setDtmf:true];
[threeButton setDigit:'3'];
[threeButton setDtmf:true];
[fourButton setDigit:'4'];
[fourButton setDtmf:true];
[fiveButton setDigit:'5'];
[fiveButton setDtmf:true];
[sixButton setDigit:'6'];
[sixButton setDtmf:true];
[sevenButton setDigit:'7'];
[sevenButton setDtmf:true];
[eightButton setDigit:'8'];
[eightButton setDtmf:true];
[nineButton setDigit:'9'];
[nineButton setDtmf:true];
[starButton setDigit:'*'];
[starButton setDtmf:true];
[sharpButton setDigit:'#'];
[sharpButton setDtmf:true];
{
UIButton *videoButtonLandscape = (UIButton*)[landscapeView viewWithTag:[videoButton tag]];
// Set selected+disabled background: IB lack !
[videoButton setBackgroundImage:[UIImage imageNamed:@"video_on_disabled.png"]
forState:(UIControlStateDisabled | UIControlStateSelected)];
[videoButtonLandscape setBackgroundImage:[UIImage imageNamed:@"video_on_disabled_landscape.png"]
forState:(UIControlStateDisabled | UIControlStateSelected)];
// Set selected+over background: IB lack !
[videoButton setBackgroundImage:[UIImage imageNamed:@"video_on_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[videoButtonLandscape setBackgroundImage:[UIImage imageNamed:@"video_on_over_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:videoButton];
[LinphoneUtils buttonFixStates:videoButtonLandscape];
}
{
UIButton *speakerButtonLandscape = (UIButton*) [landscapeView viewWithTag:[speakerButton tag]];
// Set selected+disabled background: IB lack !
[speakerButton setBackgroundImage:[UIImage imageNamed:@"speaker_on_disabled.png"]
forState:(UIControlStateDisabled | UIControlStateSelected)];
[speakerButtonLandscape setBackgroundImage:[UIImage imageNamed:@"speaker_on_disabled_landscape.png"]
forState:(UIControlStateDisabled | UIControlStateSelected)];
// Set selected+over background: IB lack !
[speakerButton setBackgroundImage:[UIImage imageNamed:@"speaker_on_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[speakerButtonLandscape setBackgroundImage:[UIImage imageNamed:@"sspeaker_on_over_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:speakerButton];
[LinphoneUtils buttonFixStates:speakerButtonLandscape];
}
{
UIButton *microButtonLandscape = (UIButton*) [landscapeView viewWithTag:[microButton tag]];
// Set selected+disabled background: IB lack !
[microButton setBackgroundImage:[UIImage imageNamed:@"micro_on_disabled.png"]
forState:(UIControlStateDisabled | UIControlStateSelected)];
[microButtonLandscape setBackgroundImage:[UIImage imageNamed:@"micro_on_disabled_landscape.png"]
forState:(UIControlStateDisabled | UIControlStateSelected)];
// Set selected+over background: IB lack !
[microButton setBackgroundImage:[UIImage imageNamed:@"micro_on_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[microButtonLandscape setBackgroundImage:[UIImage imageNamed:@"micro_on_over_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:microButton];
[LinphoneUtils buttonFixStates:microButtonLandscape];
}
{
UIButton *optionsButtonLandscape = (UIButton*) [landscapeView viewWithTag:[optionsButton tag]];
// Set selected+over background: IB lack !
[optionsButton setBackgroundImage:[UIImage imageNamed:@"options_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[optionsButtonLandscape setBackgroundImage:[UIImage imageNamed:@"options_over_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:optionsButton];
[LinphoneUtils buttonFixStates:optionsButtonLandscape];
}
{
UIButton *pauseButtonLandscape = (UIButton*) [landscapeView viewWithTag:[pauseButton tag]];
// Set selected+over background: IB lack !
[pauseButton setBackgroundImage:[UIImage imageNamed:@"pause_on_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[pauseButtonLandscape setBackgroundImage:[UIImage imageNamed:@"pause_on_over_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:pauseButton];
[LinphoneUtils buttonFixStates:pauseButtonLandscape];
}
{
UIButton *dialerButtonLandscape = (UIButton*) [landscapeView viewWithTag:[dialerButton tag]] ;
// Set selected+over background: IB lack !
[dialerButton setBackgroundImage:[UIImage imageNamed:@"dialer_alt_back_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[dialerButtonLandscape setBackgroundImage:[UIImage imageNamed:@"dialer_alt_back_over_landscape.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[LinphoneUtils buttonFixStates:dialerButton];
[LinphoneUtils buttonFixStates:dialerButtonLandscape];
}
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate
object:nil];
// Update on show
LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]);
LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0;
[self callUpdate:call state:state];
[self hideOptions:FALSE];
[self hidePad:FALSE];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCallUpdate
object:nil];
if (linphone_core_get_calls_nb([LinphoneManager getLc]) == 0) {
//reseting speaker button because no more call
speakerButton.selected=FALSE;
}
}
#pragma mark - Event Functions
- (void)callUpdateEvent:(NSNotification*)notif {
LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue];
LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue];
[self callUpdate:call state:state];
}
#pragma mark -
- (void)callUpdate:(LinphoneCall*)call state:(LinphoneCallState)state {
if(![LinphoneManager isLcReady]) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call bar: Linphone core not ready"];
return;
}
LinphoneCore* lc = [LinphoneManager getLc];
[speakerButton update];
[microButton update];
[pauseButton update];
[videoButton update];
[hangupButton update];
// Show Pause/Conference button following call count
if(linphone_core_get_calls_nb(lc) > 1) {
if(![pauseButton isHidden]) {
[pauseButton setHidden:true];
[conferenceButton setHidden:false];
}
bool enabled = true;
const MSList *list = linphone_core_get_calls(lc);
while(list != NULL) {
LinphoneCall *call = (LinphoneCall*) list->data;
LinphoneCallState state = linphone_call_get_state(call);
if(state == LinphoneCallIncomingReceived ||
state == LinphoneCallOutgoingInit ||
state == LinphoneCallOutgoingProgress ||
state == LinphoneCallOutgoingRinging ||
state == LinphoneCallOutgoingEarlyMedia ||
state == LinphoneCallConnected) {
enabled = false;
}
list = list->next;
}
[conferenceButton setEnabled:enabled];
} else {
if([pauseButton isHidden]) {
[pauseButton setHidden:false];
[conferenceButton setHidden:true];
}
}
// Disable transfert in conference
if(linphone_core_get_current_call(lc) == NULL) {
[optionsTransferButton setEnabled:FALSE];
} else {
[optionsTransferButton setEnabled:TRUE];
}
switch(state) {
LinphoneCallEnd:
LinphoneCallError:
LinphoneCallIncoming:
LinphoneCallOutgoing:
[self hidePad:TRUE];
[self hideOptions:TRUE];
default:
break;
}
}
#pragma mark -
- (void)showAnimation:(NSString*)animationID target:(UIView*)target completion:(void (^)(BOOL finished))completion {
CGRect frame = [target frame];
int original_y = frame.origin.y;
frame.origin.y = [[self view] frame].size.height;
[target setFrame:frame];
[target setHidden:FALSE];
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
CGRect frame = [target frame];
frame.origin.y = original_y;
[target setFrame:frame];
}
completion:^(BOOL finished){
CGRect frame = [target frame];
frame.origin.y = original_y;
[target setFrame:frame];
completion(finished);
}];
}
- (void)hideAnimation:(NSString*)animationID target:(UIView*)target completion:(void (^)(BOOL finished))completion {
CGRect frame = [target frame];
int original_y = frame.origin.y;
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
CGRect frame = [target frame];
frame.origin.y = [[self view] frame].size.height;
[target setFrame:frame];
}
completion:^(BOOL finished){
CGRect frame = [target frame];
frame.origin.y = original_y;
[target setHidden:TRUE];
[target setFrame:frame];
completion(finished);
}];
}
- (void)showPad:(BOOL)animated {
[dialerButton setOn];
if([padView isHidden]) {
if(animated) {
[self showAnimation:@"show" target:padView completion:^(BOOL finished){}];
} else {
[padView setHidden:FALSE];
}
}
}
- (void)hidePad:(BOOL)animated {
[dialerButton setOff];
if(![padView isHidden]) {
if(animated) {
[self hideAnimation:@"hide" target:padView completion:^(BOOL finished){}];
} else {
[padView setHidden:TRUE];
}
}
}
- (void)showOptions:(BOOL)animated {
[optionsButton setOn];
if([optionsView isHidden]) {
if(animated) {
[self showAnimation:@"show" target:optionsView completion:^(BOOL finished){}];
} else {
[optionsView setHidden:FALSE];
}
}
}
- (void)hideOptions:(BOOL)animated {
[optionsButton setOff];
if(![optionsView isHidden]) {
if(animated) {
[self hideAnimation:@"hide" target:optionsView completion:^(BOOL finished){}];
} else {
[optionsView setHidden:TRUE];
}
}
}
#pragma mark - Action Functions
- (IBAction)onPadClick:(id)sender {
if([padView isHidden]) {
[self showPad:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]];
} else {
[self hidePad:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]];
}
}
- (IBAction)onOptionsTransferClick:(id)sender {
[self hideOptions:TRUE];
// Go to dialer view
DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
if(controller != nil) {
[controller setAddress:@""];
[controller setTransferMode:TRUE];
}
}
- (IBAction)onOptionsAddClick:(id)sender {
[self hideOptions:TRUE];
// Go to dialer view
DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
if(controller != nil) {
[controller setAddress:@""];
[controller setTransferMode:FALSE];
}
}
- (IBAction)onOptionsClick:(id)sender {
if([optionsView isHidden]) {
[self showOptions:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]];
} else {
[self hideOptions:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]];
}
}
- (IBAction)onConferenceClick:(id)sender {
linphone_core_add_all_to_conference([LinphoneManager getLc]);
}
#pragma mark - TPMultiLayoutViewController Functions
- (NSDictionary*)attributesForView:(UIView*)view {
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
[attributes setObject:[NSValue valueWithCGRect:view.frame] forKey:@"frame"];
[attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"];
if([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
[LinphoneUtils buttonMultiViewAddAttributes:attributes button:button];
}
[attributes setObject:[NSNumber numberWithInteger:view.autoresizingMask] forKey:@"autoresizingMask"];
return attributes;
}
- (void)applyAttributes:(NSDictionary*)attributes toView:(UIView*)view {
view.frame = [[attributes objectForKey:@"frame"] CGRectValue];
view.bounds = [[attributes objectForKey:@"bounds"] CGRectValue];
if([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
[LinphoneUtils buttonMultiViewApplyAttributes:attributes button:button];
}
view.autoresizingMask = [[attributes objectForKey:@"autoresizingMask"] integerValue];
}
@end

View file

@ -21,12 +21,8 @@
@interface UICallButton : UIButton {
@private
UITextField* mAddress;
}
-(void) initWithAddress:(UITextField*) address;
+(void) enableTransforMode:(BOOL) enable;
+(BOOL) transforModeEnabled;
@property (nonatomic, retain) IBOutlet UITextField* addressField;
@end

View file

@ -19,116 +19,61 @@
#import "UICallButton.h"
#import "LinphoneManager.h"
#import "CoreTelephony/CTCallCenter.h"
#import <CoreTelephony/CTCallCenter.h>
@implementation UICallButton
static BOOL transferMode = NO;
@synthesize addressField;
+(void) enableTransforMode:(BOOL) enable {
transferMode = enable;
#pragma mark - Lifecycle Functions
- (void)initUICallButton {
[self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
}
+(BOOL) transforModeEnabled {
return transferMode;
}
-(void) touchUp:(id) sender {
if (!linphone_core_is_network_reachable([LinphoneManager getLc])) {
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Network Error",nil)
message:NSLocalizedString(@"There is no network connection available, enable WIFI or WWAN prior to place a call",nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil];
[error show];
[error release];
return;
}
CTCallCenter* ct = [[CTCallCenter alloc] init];
if ([ct.currentCalls count] > 0) {
ms_error("GSM call in progress, cancelling outgoing SIP call request");
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot make call",nil)
message:NSLocalizedString(@"Please terminate GSM call",nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil];
[error show];
[error release];
[ct release];
return;
- (id)init {
self = [super init];
if (self) {
[self initUICallButton];
}
[ct release];
if (TRUE /*!linphone_core_in_call([LinphoneManager getLc])*/) {
LinphoneProxyConfig* proxyCfg;
//get default proxy
linphone_core_get_default_proxy([LinphoneManager getLc],&proxyCfg);
LinphoneCallParams* lcallParams = linphone_core_create_default_call_parameters([LinphoneManager getLc]);
if ([mAddress.text length] == 0) return; //just return
if ([mAddress.text hasPrefix:@"sip:"]) {
if (transferMode) {
linphone_core_transfer_call([LinphoneManager getLc], linphone_core_get_current_call([LinphoneManager getLc]), [mAddress.text cStringUsingEncoding:[NSString defaultCStringEncoding]]);
} else {
linphone_core_invite_with_params([LinphoneManager getLc],[mAddress.text cStringUsingEncoding:[NSString defaultCStringEncoding]],lcallParams);
}
[UICallButton enableTransforMode:NO];
} else if ( proxyCfg==nil){
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid sip address",nil)
message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to place a call or use a valid sip address (I.E sip:john@example.net)",nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil];
[error show];
[error release];
} else {
char normalizedUserName[256];
NSString* toUserName = [NSString stringWithString:[mAddress text]];
NSString* lDisplayName = [[LinphoneManager instance] getDisplayNameFromAddressBook:toUserName andUpdateCallLog:nil];
linphone_proxy_config_normalize_number(proxyCfg,[toUserName cStringUsingEncoding:[NSString defaultCStringEncoding]],normalizedUserName,sizeof(normalizedUserName));
LinphoneAddress* tmpAddress = linphone_address_new(linphone_core_get_identity([LinphoneManager getLc]));
linphone_address_set_username(tmpAddress,normalizedUserName);
linphone_address_set_display_name(tmpAddress,(lDisplayName)?[lDisplayName cStringUsingEncoding:[NSString defaultCStringEncoding]]:nil);
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initUICallButton];
}
return self;
}
if (transferMode) {
linphone_core_transfer_call([LinphoneManager getLc], linphone_core_get_current_call([LinphoneManager getLc]), normalizedUserName);
} else {
linphone_core_invite_address_with_params([LinphoneManager getLc],tmpAddress,lcallParams) ;
}
linphone_address_destroy(tmpAddress);
}
linphone_call_params_destroy(lcallParams);
[UICallButton enableTransforMode:NO];
} else if (linphone_core_inc_invite_pending([LinphoneManager getLc])) {
linphone_core_accept_call([LinphoneManager getLc],linphone_core_get_current_call([LinphoneManager getLc]));
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self initUICallButton];
}
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code.
}
*/
-(void) initWithAddress:(UITextField*) address{
mAddress=[address retain];
transferMode = NO;
[self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (void)dealloc {
[addressField release];
[super dealloc];
[mAddress release];
}
#pragma mark -
- (void)touchUp:(id) sender {
NSString *address = [addressField text];
NSString *displayName = nil;
ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:address];
if(contact) {
displayName = [FastAddressBook getContactDisplayName:contact];
}
[[LinphoneManager instance] call:address displayName:displayName transfer:FALSE];
}
@end

View file

@ -0,0 +1,106 @@
/* UICallCell.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#include "linphonecore.h"
#include "UIPauseButton.h"
typedef enum _UICallCellOtherView {
UICallCellOtherView_Avatar = 0,
UICallCellOtherView_AudioStats,
UICallCellOtherView_VideoStats,
UICallCellOtherView_MAX
} UICallCellOtherView;
@interface UICallCellData : NSObject {
@public
bool minimize;
UICallCellOtherView view;
LinphoneCall *call;
}
- (id)init:(LinphoneCall*) call;
@property (nonatomic, retain) UIImage *image;
@property (nonatomic, retain) NSString *address;
@end
@interface UICallCell : UITableViewCell {
}
@property (nonatomic, retain) UICallCellData *data;
@property (nonatomic, retain) IBOutlet UIImageView* headerBackgroundImage;
@property (nonatomic, retain) IBOutlet UIImageView* headerBackgroundHighlightImage;
@property (nonatomic, retain) IBOutlet UILabel* addressLabel;
@property (nonatomic, retain) IBOutlet UILabel* stateLabel;
@property (nonatomic, retain) IBOutlet UIImageView* stateImage;
@property (nonatomic, retain) IBOutlet UIImageView* avatarImage;
@property (nonatomic, retain) IBOutlet UIButton *removeButton;
@property (nonatomic, retain) IBOutlet UIPauseButton *pauseButton;
@property (nonatomic, retain) IBOutlet UIView* headerView;
@property (nonatomic, retain) IBOutlet UIView* avatarView;
@property (nonatomic, retain) IBOutlet UIView* audioStatsView;
@property (nonatomic, retain) IBOutlet UILabel* audioCodecLabel;
@property (nonatomic, retain) IBOutlet UILabel* audioCodecHeaderLabel;
@property (nonatomic, retain) IBOutlet UILabel* audioUploadBandwidthLabel;
@property (nonatomic, retain) IBOutlet UILabel* audioUploadBandwidthHeaderLabel;
@property (nonatomic, retain) IBOutlet UILabel* audioDownloadBandwidthLabel;
@property (nonatomic, retain) IBOutlet UILabel* audioDownloadBandwidthHeaderLabel;
@property (nonatomic, retain) IBOutlet UILabel* audioIceConnectivityLabel;
@property (nonatomic, retain) IBOutlet UILabel* audioIceConnectivityHeaderLabel;
@property (nonatomic, retain) IBOutlet UIView* videoStatsView;
@property (nonatomic, retain) IBOutlet UILabel* videoCodecLabel;
@property (nonatomic, retain) IBOutlet UILabel* videoCodecHeaderLabel;
@property (nonatomic, retain) IBOutlet UILabel* videoUploadBandwidthLabel;
@property (nonatomic, retain) IBOutlet UILabel* videoUploadBandwidthHeaderLabel;
@property (nonatomic, retain) IBOutlet UILabel* videoDownloadBandwidthLabel;
@property (nonatomic, retain) IBOutlet UILabel* videoDownloadBandwidthHeaderLabel;
@property (nonatomic, retain) IBOutlet UILabel* videoIceConnectivityLabel;
@property (nonatomic, retain) IBOutlet UILabel* videoIceConnectivityHeaderLabel;
@property (nonatomic, retain) IBOutlet UIView* otherView;
@property (nonatomic, retain) IBOutlet UISwipeGestureRecognizer *detailsLeftSwipeGestureRecognizer;
@property (nonatomic, retain) IBOutlet UISwipeGestureRecognizer *detailsRightSwipeGestureRecognizer;
@property (assign) BOOL firstCell;
@property (assign) BOOL conferenceCell;
@property (nonatomic, assign) BOOL currentCall;
- (void)update;
- (id)initWithIdentifier:(NSString*)identifier;
- (IBAction)doHeaderClick:(id)sender;
- (IBAction)doRemoveClick:(id)sender;
- (IBAction)doDetailsSwipe:(UISwipeGestureRecognizer *)sender;
+ (int)getMaximizedHeight;
+ (int)getMinimizedHeight;
@end

View file

@ -0,0 +1,556 @@
/* UICallCell.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <QuartzCore/QuartzCore.h>
#import "UICallCell.h"
#import "UILinphone.h"
#import "LinphoneManager.h"
#import "FastAddressBook.h"
@implementation UICallCellData
@synthesize address;
@synthesize image;
- (id)init:(LinphoneCall*) acall {
self = [super init];
if(self != nil) {
self->minimize = false;
self->view = UICallCellOtherView_Avatar;
self->call = acall;
image = [[UIImage imageNamed:@"avatar_unknown.png"] retain];
address = [@"Unknown" retain];
[self update];
}
return self;
}
- (void)update {
if(call == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"];
return;
}
const LinphoneAddress* addr = linphone_call_get_remote_address(call);
if(addr != NULL) {
BOOL useLinphoneAddress = true;
// contact name
char* lAddress = linphone_address_as_string_uri_only(addr);
if(lAddress) {
NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]];
ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress];
if(contact) {
useLinphoneAddress = false;
self.address = [FastAddressBook getContactDisplayName:contact];
UIImage *tmpImage = [FastAddressBook getContactImage:contact thumbnail:false];
if(tmpImage != nil) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) {
UIImage *tmpImage2 = [UIImage decodedImageWithImage:tmpImage];
dispatch_async(dispatch_get_main_queue(), ^{
[self setImage: tmpImage2];
});
});
}
}
ms_free(lAddress);
}
if(useLinphoneAddress) {
const char* lDisplayName = linphone_address_get_display_name(addr);
const char* lUserName = linphone_address_get_username(addr);
if (lDisplayName)
self.address = [NSString stringWithUTF8String:lDisplayName];
else if(lUserName)
self.address = [NSString stringWithUTF8String:lUserName];
}
}
}
- (void)dealloc {
[address release];
[image release];
[super dealloc];
}
@end
@implementation UICallCell
@synthesize data;
@synthesize headerBackgroundImage;
@synthesize headerBackgroundHighlightImage;
@synthesize addressLabel;
@synthesize stateLabel;
@synthesize stateImage;
@synthesize avatarImage;
@synthesize pauseButton;
@synthesize removeButton;
@synthesize headerView;
@synthesize avatarView;
@synthesize audioStatsView;
@synthesize audioCodecLabel;
@synthesize audioCodecHeaderLabel;
@synthesize audioUploadBandwidthLabel;
@synthesize audioUploadBandwidthHeaderLabel;
@synthesize audioDownloadBandwidthLabel;
@synthesize audioDownloadBandwidthHeaderLabel;
@synthesize audioIceConnectivityLabel;
@synthesize audioIceConnectivityHeaderLabel;
@synthesize videoStatsView;
@synthesize videoCodecLabel;
@synthesize videoCodecHeaderLabel;
@synthesize videoUploadBandwidthLabel;
@synthesize videoUploadBandwidthHeaderLabel;
@synthesize videoDownloadBandwidthLabel;
@synthesize videoDownloadBandwidthHeaderLabel;
@synthesize videoIceConnectivityLabel;
@synthesize videoIceConnectivityHeaderLabel;
@synthesize otherView;
@synthesize firstCell;
@synthesize conferenceCell;
@synthesize currentCall;
@synthesize detailsLeftSwipeGestureRecognizer;
@synthesize detailsRightSwipeGestureRecognizer;
#pragma mark - Lifecycle Functions
- (id)initWithIdentifier:(NSString*)identifier {
if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) {
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UICallCell"
owner:self
options:nil];
if ([arrayOfViews count] >= 1) {
[self addSubview:[[arrayOfViews objectAtIndex:0] retain]];
}
// Set selected+over background: IB lack !
[pauseButton setImage:[UIImage imageNamed:@"call_state_pause_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
self->currentCall = FALSE;
self->detailsRightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(doDetailsSwipe:)];
[detailsRightSwipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft];
[otherView addGestureRecognizer:detailsRightSwipeGestureRecognizer];
self->detailsRightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(doDetailsSwipe:)];
[detailsRightSwipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionRight];
[otherView addGestureRecognizer:detailsRightSwipeGestureRecognizer];
[self->avatarView setHidden:TRUE];
[self->audioStatsView setHidden:TRUE];
[self->videoStatsView setHidden:TRUE];
[UICallCell adaptSize:audioCodecHeaderLabel field:audioCodecLabel];
[UICallCell adaptSize:audioDownloadBandwidthHeaderLabel field:audioDownloadBandwidthLabel];
[UICallCell adaptSize:audioUploadBandwidthHeaderLabel field:audioUploadBandwidthLabel];
[UICallCell adaptSize:audioIceConnectivityHeaderLabel field:audioIceConnectivityLabel];
[UICallCell adaptSize:videoCodecHeaderLabel field:videoCodecLabel];
[UICallCell adaptSize:videoDownloadBandwidthHeaderLabel field:videoDownloadBandwidthLabel];
[UICallCell adaptSize:videoUploadBandwidthHeaderLabel field:videoUploadBandwidthLabel];
[UICallCell adaptSize:videoIceConnectivityHeaderLabel field:videoIceConnectivityLabel];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification
object:nil];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationWillEnterForegroundNotification
object:nil];
[headerBackgroundImage release];
[headerBackgroundHighlightImage release];
[addressLabel release];
[stateLabel release];
[stateImage release];
[avatarImage release];
[pauseButton release];
[removeButton release];
[headerView release];
[avatarView release];
[audioStatsView release];
[audioCodecLabel release];
[audioCodecHeaderLabel release];
[audioUploadBandwidthLabel release];
[audioUploadBandwidthHeaderLabel release];
[audioDownloadBandwidthLabel release];
[audioDownloadBandwidthHeaderLabel release];
[audioIceConnectivityLabel release];
[audioIceConnectivityHeaderLabel release];
[videoStatsView release];
[videoCodecLabel release];
[videoCodecHeaderLabel release];
[videoUploadBandwidthLabel release];
[videoUploadBandwidthHeaderLabel release];
[videoDownloadBandwidthLabel release];
[videoDownloadBandwidthHeaderLabel release];
[videoIceConnectivityLabel release];
[videoIceConnectivityHeaderLabel release];
[otherView release];
[data release];
[detailsLeftSwipeGestureRecognizer release];
[detailsRightSwipeGestureRecognizer release];
[super dealloc];
}
- (void)prepareForReuse {
}
#pragma mark - Properties Functions
- (void)setData:(UICallCellData *)adata {
if(adata == data) {
return;
}
if(data != nil) {
[data release];
data = nil;
}
if(adata != nil) {
data = [adata retain];
}
}
- (void)setCurrentCall:(BOOL) val {
currentCall = val;
if (currentCall && ![self isBlinkAnimationRunning:@"blink" target:headerBackgroundHighlightImage]) {
[self startBlinkAnimation:@"blink" target:headerBackgroundHighlightImage];
}
if (!currentCall) {
[self stopBlinkAnimation:@"blink" target:headerBackgroundHighlightImage];
}
}
#pragma mark - Static Functions
+ (int)getMaximizedHeight {
return 280;
}
+ (int)getMinimizedHeight {
return 54;
}
+ (void)adaptSize:(UILabel*)label field:(UIView*)field {
//
// Adapt size
//
CGRect labelFrame = [label frame];
CGRect fieldFrame = [field frame];
fieldFrame.origin.x -= labelFrame.size.width;
// Compute firstName size
CGSize contraints;
contraints.height = [label frame].size.height;
contraints.width = ([field frame].size.width + [field frame].origin.x) - [label frame].origin.x;
CGSize firstNameSize = [[label text] sizeWithFont:[label font] constrainedToSize: contraints];
labelFrame.size.width = firstNameSize.width;
// Compute lastName size & position
fieldFrame.origin.x += labelFrame.size.width;
fieldFrame.size.width = (contraints.width + [label frame].origin.x) - fieldFrame.origin.x;
[label setFrame: labelFrame];
[field setFrame: fieldFrame];
}
+ (NSString*)iceToString:(LinphoneIceState)state {
switch (state) {
case LinphoneIceStateNotActivated:
return NSLocalizedString(@"Not activated", @"ICE has not been activated for this call");
break;
case LinphoneIceStateFailed:
return NSLocalizedString(@"Failed", @"ICE processing has failed");
break;
case LinphoneIceStateInProgress:
return NSLocalizedString(@"In progress", @"ICE process is in progress");
break;
case LinphoneIceStateHostConnection:
return NSLocalizedString(@"Direct connection", @"ICE has established a direct connection to the remote host");
break;
case LinphoneIceStateReflexiveConnection:
return NSLocalizedString(@"NAT(s) connection", @"ICE has established a connection to the remote host through one or several NATs");
break;
case LinphoneIceStateRelayConnection:
return NSLocalizedString(@"Relay connection", @"ICE has established a connection through a relay");
break;
}
}
#pragma mark - Event Functions
- (void)applicationWillEnterForeground:(NSNotification*)notif {
if (currentCall) {
[self startBlinkAnimation:@"blink" target:headerBackgroundHighlightImage];
}
}
#pragma mark - Animation Functions
- (void)startBlinkAnimation:(NSString *)animationID target:(UIView *)target {
CABasicAnimation *blink = [CABasicAnimation animationWithKeyPath:@"opacity"];
blink.duration = 1.0;
blink.fromValue = [NSNumber numberWithDouble:0.0f];
blink.toValue = [NSNumber numberWithDouble:1.0f];
blink.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
blink.autoreverses = TRUE;
blink.repeatCount = HUGE_VALF;
[target.layer addAnimation:blink forKey:animationID];
}
- (BOOL)isBlinkAnimationRunning:(NSString *)animationID target:(UIView *)target {
return [target.layer animationForKey:animationID] != nil;
}
- (void)stopBlinkAnimation:(NSString *)animationID target:(UIView *)target {
[target.layer removeAnimationForKey:animationID];
[target setAlpha:0.0f];
}
#pragma mark -
- (void)update {
if(data == nil || data->call == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"];
return;
}
LinphoneCall *call = data->call;
[pauseButton setType:UIPauseButtonType_Call call:call];
[addressLabel setText:data.address];
[avatarImage setImage:data.image];
LinphoneCallState state = linphone_call_get_state(call);
if(!conferenceCell) {
if(state == LinphoneCallOutgoingRinging) {
[stateImage setImage:[UIImage imageNamed:@"call_state_ringing_default.png"]];
[stateImage setHidden:false];
[pauseButton setHidden:true];
} else if(state == LinphoneCallOutgoingInit || state == LinphoneCallOutgoingProgress){
[stateImage setImage:[UIImage imageNamed:@"call_state_outgoing_default.png"]];
[stateImage setHidden:false];
[pauseButton setHidden:true];
} else {
[stateImage setHidden:true];
[pauseButton setHidden:false];
[pauseButton update];
}
[removeButton setHidden:true];
if(firstCell) {
[headerBackgroundImage setImage:[UIImage imageNamed:@"cell_call_first.png"]];
[headerBackgroundHighlightImage setImage:[UIImage imageNamed:@"cell_call_first_highlight.png"]];
} else {
[headerBackgroundImage setImage:[UIImage imageNamed:@"cell_call.png"]];
[headerBackgroundHighlightImage setImage:[UIImage imageNamed:@"cell_call_highlight.png"]];
}
} else {
[stateImage setHidden:true];
[pauseButton setHidden:true];
[removeButton setHidden:false];
[headerBackgroundImage setImage:[UIImage imageNamed:@"cell_conference.png"]];
}
int duration = linphone_call_get_duration(call);
[stateLabel setText:[NSString stringWithFormat:@"%02i:%02i", (duration/60), duration - 60 * (duration / 60), nil]];
if(!data->minimize) {
CGRect frame = [self frame];
frame.size.height = [otherView frame].size.height;
[self setFrame:frame];
[otherView setHidden:false];
} else {
CGRect frame = [self frame];
frame.size.height = [headerView frame].size.height;
[self setFrame:frame];
[otherView setHidden:true];
}
[self updateStats];
[self updateDetailsView];
}
- (void)updateStats {
if(data == nil || data->call == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"];
return;
}
LinphoneCall *call = data->call;
const LinphoneCallParams *params = linphone_call_get_current_params(call);
{
const PayloadType* payload = linphone_call_params_get_used_audio_codec(params);
if(payload != NULL) {
[audioCodecLabel setText:[NSString stringWithFormat:@"%s/%i/%i", payload->mime_type, payload->clock_rate, payload->channels]];
} else {
[audioCodecLabel setText:NSLocalizedString(@"No codec", nil)];
}
const LinphoneCallStats *stats = linphone_call_get_audio_stats(call);
if(stats != NULL) {
[audioUploadBandwidthLabel setText:[NSString stringWithFormat:@"%1.1f kbits/s", stats->upload_bandwidth]];
[audioDownloadBandwidthLabel setText:[NSString stringWithFormat:@"%1.1f kbits/s", stats->download_bandwidth]];
[audioIceConnectivityLabel setText:[UICallCell iceToString:stats->ice_state]];
} else {
[audioUploadBandwidthLabel setText:@""];
[audioDownloadBandwidthLabel setText:@""];
[audioIceConnectivityLabel setText:@""];
}
}
{
const PayloadType* payload = linphone_call_params_get_used_video_codec(params);
if(payload != NULL) {
[videoCodecLabel setText:[NSString stringWithFormat:@"%s/%i", payload->mime_type, payload->clock_rate]];
} else {
[videoCodecLabel setText:NSLocalizedString(@"No codec", nil)];
}
const LinphoneCallStats *stats = linphone_call_get_video_stats(call);
if(stats != NULL) {
[videoUploadBandwidthLabel setText:[NSString stringWithFormat:@"%1.1f kbits/s", stats->upload_bandwidth]];
[videoDownloadBandwidthLabel setText:[NSString stringWithFormat:@"%1.1f kbits/s", stats->download_bandwidth]];
[videoIceConnectivityLabel setText:[UICallCell iceToString:stats->ice_state]];
} else {
[videoUploadBandwidthLabel setText:@""];
[videoDownloadBandwidthLabel setText:@""];
[videoIceConnectivityLabel setText:@""];
}
}
}
- (void)updateDetailsView {
if(data == nil || data->call == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"];
return;
}
if(data->view == UICallCellOtherView_Avatar && avatarView.isHidden) {
[self->avatarView setHidden:FALSE];
[self->audioStatsView setHidden:TRUE];
[self->videoStatsView setHidden:TRUE];
} else if(data->view == UICallCellOtherView_AudioStats && audioStatsView.isHidden) {
[self->avatarView setHidden:TRUE];
[self->audioStatsView setHidden:FALSE];
[self->videoStatsView setHidden:TRUE];
} else if(data->view == UICallCellOtherView_VideoStats && videoStatsView.isHidden) {
[self->avatarView setHidden:TRUE];
[self->audioStatsView setHidden:TRUE];
[self->videoStatsView setHidden:FALSE];
}
}
- (void)selfUpdate {
UITableView *parentTable = (UITableView *)self.superview;
if(parentTable) {
NSIndexPath *index= [parentTable indexPathForCell:self];
if(index != nil) {
[parentTable reloadRowsAtIndexPaths:[[NSArray alloc] initWithObjects:index, nil] withRowAnimation:false];
}
}
}
#pragma mark - Action Functions
- (IBAction)doHeaderClick:(id)sender {
if(data) {
data->minimize = !data->minimize;
[self selfUpdate];
}
}
- (IBAction)doRemoveClick:(id)sender {
if(data != nil && data->call != NULL) {
linphone_core_remove_from_conference([LinphoneManager getLc], data->call);
}
}
- (IBAction)doDetailsSwipe:(UISwipeGestureRecognizer *)sender {
CATransition* trans = nil;
if(data != nil) {
if (sender.direction == UISwipeGestureRecognizerDirectionLeft) {
if(data->view == UICallCellOtherView_MAX - 1) {
data->view = 0;
} else {
++data->view;
}
trans = [CATransition animation];
[trans setType:kCATransitionPush];
[trans setDuration:0.35];
[trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[trans setSubtype:kCATransitionFromRight];
} else if (sender.direction == UISwipeGestureRecognizerDirectionRight) {
if(data->view == 0) {
data->view = UICallCellOtherView_MAX - 1;
} else {
--data->view;
}
trans = [CATransition animation];
[trans setType:kCATransitionPush];
[trans setDuration:0.35];
[trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[trans setSubtype:kCATransitionFromLeft];
}
if(trans) {
[otherView.layer removeAnimationForKey:@"transition"];
[otherView.layer addAnimation:trans forKey:@"transition"];
[self updateDetailsView];
}
}
}
@end

View file

@ -21,11 +21,9 @@
@interface UICamSwitch : UIButton {
@private
const char* currentCamId;
const char* nextCamId;
UIView* preview;
}
@property (nonatomic, retain) IBOutlet UIView* preview;
@end

View file

@ -20,24 +20,13 @@
#import "UICamSwitch.h"
#include "LinphoneManager.h"
@implementation UICamSwitch
@synthesize preview;
-(void) touchUp:(id) sender {
if (nextCamId!=currentCamId) {
ms_message("Switching from [%s] to [%s]",currentCamId,nextCamId);
linphone_core_set_video_device([LinphoneManager getLc], nextCamId);
nextCamId=currentCamId;
currentCamId = linphone_core_get_video_device([LinphoneManager getLc]);
linphone_core_update_call([LinphoneManager getLc]
, linphone_core_get_current_call([LinphoneManager getLc])
,NULL);
linphone_core_set_native_preview_window_id([LinphoneManager getLc],
(unsigned long)preview);
}
}
- (id) init {
#pragma mark - Lifecycle Functions
- (id)initUICamSwitch {
[self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
currentCamId = (char*)linphone_core_get_video_device([LinphoneManager getLc]);
if ([LinphoneManager instance].frontCamId !=nil ) {
@ -52,18 +41,28 @@
}
return self;
}
- (id)init {
self = [super init];
if (self) {
[self initUICamSwitch];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self init];
[self initUICamSwitch];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self init];
[self initUICamSwitch];
}
return self;
}
@ -75,7 +74,23 @@
}
#pragma mark -
-(void) touchUp:(id) sender {
if(![LinphoneManager isLcReady]) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot tigger camswitch button: Linphone core not ready"];
return;
}
if (nextCamId != currentCamId) {
[LinphoneLogger logc:LinphoneLoggerLog format:"Switching from [%s] to [%s]", currentCamId, nextCamId];
linphone_core_set_video_device([LinphoneManager getLc], nextCamId);
nextCamId = currentCamId;
currentCamId = linphone_core_get_video_device([LinphoneManager getLc]);
LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]);
if(call != NULL) {
linphone_core_update_call([LinphoneManager getLc], call, NULL);
}
}
}
@end

View file

@ -0,0 +1,39 @@
/* UIChatCell.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "ChatModel.h"
@interface UIChatCell : UITableViewCell {
}
@property (nonatomic, retain) ChatModel *chat;
@property (nonatomic, retain) IBOutlet UIImageView *avatarImage;
@property (nonatomic, retain) IBOutlet UILabel* addressLabel;
@property (nonatomic, retain) IBOutlet UILabel* chatContentLabel;
@property (nonatomic, retain) IBOutlet UIButton * deleteButton;
@property (nonatomic, retain) IBOutlet UIView * unreadMessageView;
@property (nonatomic, retain) IBOutlet UILabel * unreadMessageLabel;
- (id)initWithIdentifier:(NSString*)identifier;
- (IBAction)onDeleteClick:(id)event;
@end

View file

@ -0,0 +1,168 @@
/* UIChatCell.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "UIChatCell.h"
#import "PhoneMainView.h"
#import "LinphoneManager.h"
#import "Utils.h"
@implementation UIChatCell
@synthesize avatarImage;
@synthesize addressLabel;
@synthesize chatContentLabel;
@synthesize deleteButton;
@synthesize unreadMessageLabel;
@synthesize unreadMessageView;
@synthesize chat;
#pragma mark - Lifecycle Functions
- (id)initWithIdentifier:(NSString*)identifier {
if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) {
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UIChatCell"
owner:self
options:nil];
if ([arrayOfViews count] >= 1) {
[self addSubview:[[arrayOfViews objectAtIndex:0] retain]];
}
[chatContentLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack!
}
return self;
}
- (void)dealloc {
[addressLabel release];
[chatContentLabel release];
[avatarImage release];
[deleteButton release];
[unreadMessageLabel release];
[unreadMessageView release];
[chat release];
[super dealloc];
}
#pragma mark - Property Funcitons
- (void)setChat:(ChatModel *)achat {
if(chat == achat)
return;
if(chat != nil) {
[chat release];
}
if(achat) {
chat = [achat retain];
}
[self update];
}
#pragma mark -
- (void)update {
NSString *displayName = nil;
UIImage *image = nil;
if(chat == nil) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat cell: null chat"];
return;
}
LinphoneAddress* linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], [[chat remoteContact] UTF8String]);
if (linphoneAddress == NULL)
return;
char *tmp = linphone_address_as_string_uri_only(linphoneAddress);
NSString *normalizedSipAddress = [NSString stringWithUTF8String:tmp];
ms_free(tmp);
ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress];
if(contact != nil) {
displayName = [FastAddressBook getContactDisplayName:contact];
image = [FastAddressBook getContactImage:contact thumbnail:true];
}
// Display name
if(displayName == nil) {
displayName = [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)];
}
[addressLabel setText:displayName];
// Avatar
if(image == nil) {
image = [UIImage imageNamed:@"avatar_unknown_small.png"];
}
[avatarImage setImage:image];
// Message
if([chat isExternalImage] || [chat isInternalImage]) {
[chatContentLabel setText:@""];
} else {
[chatContentLabel setText:[chat message]];
}
int count = [ChatModel unreadMessages:[chat remoteContact]];
if(count > 0) {
[unreadMessageView setHidden:FALSE];
[unreadMessageLabel setText:[NSString stringWithFormat:@"%i", count]];
} else {
[unreadMessageView setHidden:TRUE];
}
linphone_address_destroy(linphoneAddress);
}
- (void)setEditing:(BOOL)editing {
[self setEditing:editing animated:FALSE];
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
if(animated) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
}
if(editing) {
[deleteButton setAlpha:1.0f];
} else {
[deleteButton setAlpha:0.0f];
}
if(animated) {
[UIView commitAnimations];
}
}
#pragma mark - Action Functions
- (IBAction)onDeleteClick: (id) event {
if(chat != NULL) {
UIView *view = [self superview];
// Find TableViewCell
if(view != nil && ![view isKindOfClass:[UITableView class]]) view = [view superview];
if(view != nil) {
UITableView *tableView = (UITableView*) view;
NSIndexPath *indexPath = [tableView indexPathForCell:self];
[[tableView dataSource] tableView:tableView commitEditingStyle:UITableViewCellEditingStyleDelete forRowAtIndexPath:indexPath];
}
}
}
@end

View file

@ -0,0 +1,471 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1536</int>
<string key="IBDocument.SystemVersion">11G63</string>
<string key="IBDocument.InterfaceBuilderVersion">2840</string>
<string key="IBDocument.AppKitVersion">1138.51</string>
<string key="IBDocument.HIToolboxVersion">569.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1926</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUIButton</string>
<string>IBUIImageView</string>
<string>IBUILabel</string>
<string>IBUIView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="316763236">
<reference key="NSNextResponder"/>
<int key="NSvFlags">290</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIImageView" id="567463562">
<reference key="NSNextResponder" ref="316763236"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{10, 8}, {44, 44}}</string>
<reference key="NSSuperview" ref="316763236"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="394118737"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">avatar_unknown_small.png</string>
</object>
</object>
<object class="IBUILabel" id="394118737">
<reference key="NSNextResponder" ref="316763236"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{62, 2}, {218, 25}}</string>
<reference key="NSSuperview" ref="316763236"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="641729677"/>
<string key="NSReuseIdentifierKey">_NS:328</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<int key="IBUITag">2</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<object class="IBUIAccessibilityConfiguration" key="IBUIAccessibilityConfiguration">
<string key="IBUIAccessibilityLabel">Firstname</string>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">John</string>
<object class="NSColor" key="IBUITextColor" id="829378485">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
<string key="IBUIColorCocoaTouchKeyPath">darkTextColor</string>
</object>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">1</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">25</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">25</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUILabel" id="641729677">
<reference key="NSNextResponder" ref="316763236"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{62, 27}, {218, 33}}</string>
<reference key="NSSuperview" ref="316763236"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="186935856"/>
<string key="NSReuseIdentifierKey">_NS:328</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<int key="IBUITag">2</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<object class="IBUIAccessibilityConfiguration" key="IBUIAccessibilityConfiguration">
<string key="IBUIAccessibilityLabel">Firstname</string>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">This is a message</string>
<reference key="IBUITextColor" ref="829378485"/>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">1</int>
<float key="IBUIMinimumFontSize">10</float>
<int key="IBUINumberOfLines">2</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">12</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">12</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
<double key="preferredMaxLayoutWidth">218</double>
</object>
<object class="IBUIView" id="186935856">
<reference key="NSNextResponder" ref="316763236"/>
<int key="NSvFlags">257</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIImageView" id="692798876">
<reference key="NSNextResponder" ref="186935856"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{10, 12}, {24, 20}}</string>
<reference key="NSSuperview" ref="186935856"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="960259784"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">bubble.png</string>
</object>
</object>
<object class="IBUILabel" id="960259784">
<reference key="NSNextResponder" ref="186935856"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{12, 10}, {20, 20}}</string>
<reference key="NSSuperview" ref="186935856"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="753878244"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">3</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MSAxIDEAA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">1</int>
</object>
</object>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">9</float>
<int key="IBUITextAlignment">1</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">14</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">14</double>
<int key="NSfFlags">16</int>
</object>
</object>
</array>
<string key="NSFrame">{{276, 8}, {44, 44}}</string>
<reference key="NSSuperview" ref="316763236"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="692798876"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor" id="886300225">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIButton" id="753878244">
<reference key="NSNextResponder" ref="316763236"/>
<int key="NSvFlags">257</int>
<string key="NSFrame">{{276, 8}, {44, 44}}</string>
<reference key="NSSuperview" ref="316763236"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<bool key="IBUIAdjustsImageWhenHighlighted">NO</bool>
<double key="IBUIImageEdgeInsets.top">11</double>
<double key="IBUIImageEdgeInsets.bottom">11</double>
<double key="IBUIImageEdgeInsets.left">11</double>
<double key="IBUIImageEdgeInsets.right">11</double>
<object class="NSColor" key="IBUINormalTitleShadowColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="NSCustomResource" key="IBUIHighlightedImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">list_delete_over.png</string>
</object>
<object class="NSCustomResource" key="IBUINormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">list_delete_default.png</string>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
</array>
<string key="NSFrameSize">{320, 60}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="567463562"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="886300225"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">chatContentLabel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="641729677"/>
</object>
<int key="connectionID">24</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">avatarImage</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="567463562"/>
</object>
<int key="connectionID">30</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">deleteButton</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="753878244"/>
</object>
<int key="connectionID">34</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">addressLabel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="394118737"/>
</object>
<int key="connectionID">38</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">unreadMessageLabel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="960259784"/>
</object>
<int key="connectionID">42</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">unreadMessageView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="186935856"/>
</object>
<int key="connectionID">43</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">onDeleteClick:</string>
<reference key="source" ref="753878244"/>
<reference key="destination" ref="372490531"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">37</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">17</int>
<reference key="object" ref="316763236"/>
<array class="NSMutableArray" key="children">
<reference ref="567463562"/>
<reference ref="641729677"/>
<reference ref="394118737"/>
<reference ref="186935856"/>
<reference ref="753878244"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">19</int>
<reference key="object" ref="567463562"/>
<reference key="parent" ref="316763236"/>
<string key="objectName">avatarImage</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">20</int>
<reference key="object" ref="394118737"/>
<reference key="parent" ref="316763236"/>
<string key="objectName">addressLabel</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">21</int>
<reference key="object" ref="641729677"/>
<reference key="parent" ref="316763236"/>
<string key="objectName">chatContentLabel</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">32</int>
<reference key="object" ref="753878244"/>
<reference key="parent" ref="316763236"/>
<string key="objectName">deleteButton</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">39</int>
<reference key="object" ref="186935856"/>
<array class="NSMutableArray" key="children">
<reference ref="692798876"/>
<reference ref="960259784"/>
</array>
<reference key="parent" ref="316763236"/>
<string key="objectName">unreadMessageView</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">40</int>
<reference key="object" ref="692798876"/>
<reference key="parent" ref="186935856"/>
<string key="objectName">unreadMessageImage</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">41</int>
<reference key="object" ref="960259784"/>
<reference key="parent" ref="186935856"/>
<string key="objectName">unreadMessageLabel</string>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">UIChatCell</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="17.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="19.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="20.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="21.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="32.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<real value="2" key="32.IBUIButtonInspectorSelectedEdgeInsetMetadataKey"/>
<real value="1" key="32.IBUIButtonInspectorSelectedStateConfigurationMetadataKey"/>
<string key="39.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="40.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="41.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">43</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">UIChatCell</string>
<string key="superclassName">UITableViewCell</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">onDeleteClick:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<string key="NS.key.0">onDeleteClick:</string>
<object class="IBActionInfo" key="NS.object.0">
<string key="name">onDeleteClick:</string>
<string key="candidateClassName">id</string>
</object>
</object>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="addressLabel">UILabel</string>
<string key="avatarImage">UIImageView</string>
<string key="chatContentLabel">UILabel</string>
<string key="deleteButton">UIButton</string>
<string key="unreadMessageLabel">UILabel</string>
<string key="unreadMessageView">UIView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="addressLabel">
<string key="name">addressLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="avatarImage">
<string key="name">avatarImage</string>
<string key="candidateClassName">UIImageView</string>
</object>
<object class="IBToOneOutletInfo" key="chatContentLabel">
<string key="name">chatContentLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="deleteButton">
<string key="name">deleteButton</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="unreadMessageLabel">
<string key="name">unreadMessageLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="unreadMessageView">
<string key="name">unreadMessageView</string>
<string key="candidateClassName">UIView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UIChatCell.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="avatar_unknown_small.png">{131, 131}</string>
<string key="bubble.png">{47, 40}</string>
<string key="list_delete_default.png">{45, 45}</string>
<string key="list_delete_over.png">{45, 45}</string>
</dictionary>
<string key="IBCocoaTouchPluginVersion">1926</string>
</data>
</archive>

View file

@ -0,0 +1,51 @@
/* UIChatRoomCell.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "ChatModel.h"
#import "ChatRoomTableViewController.h"
#import "UILoadingImageView.h"
@interface UIChatRoomCell : UITableViewCell {
}
@property (nonatomic, retain) ChatModel *chat;
@property (nonatomic, retain) IBOutlet UIView *innerView;
@property (nonatomic, retain) IBOutlet UIView *bubbleView;
@property (nonatomic, retain) IBOutlet UIImageView* backgroundImage;
@property (nonatomic, retain) IBOutlet UITextView *messageText;
@property (nonatomic, retain) IBOutlet UILoadingImageView *messageImageView;
@property (nonatomic, retain) IBOutlet UIButton *deleteButton;
@property (nonatomic, retain) IBOutlet UILabel *dateLabel;
@property (nonatomic, retain) IBOutlet UIImageView* statusImage;
@property (nonatomic, retain) IBOutlet UIButton* downloadButton;
@property (nonatomic, retain) IBOutlet UITapGestureRecognizer* imageTapGestureRecognizer;
- (id)initWithIdentifier:(NSString*)identifier;
+ (CGFloat)height:(ChatModel*)chat width:(int)width;
@property (nonatomic, retain) id<ChatRoomDelegate> chatRoomDelegate;
- (IBAction)onDeleteClick:(id)event;
- (IBAction)onDownloadClick:(id)event;
- (IBAction)onImageClick:(id)event;
@end

View file

@ -0,0 +1,287 @@
/* UIChatRoomCell.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "UIChatRoomCell.h"
#import "UILinphone.h"
#import "Utils.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import <AssetsLibrary/ALAsset.h>
#import <AssetsLibrary/ALAssetRepresentation.h>
#import <NinePatch.h>
#include "linphonecore.h"
@implementation UIChatRoomCell
@synthesize innerView;
@synthesize bubbleView;
@synthesize backgroundImage;
@synthesize messageImageView;
@synthesize messageText;
@synthesize deleteButton;
@synthesize dateLabel;
@synthesize chat;
@synthesize statusImage;
@synthesize downloadButton;
@synthesize chatRoomDelegate;
@synthesize imageTapGestureRecognizer;
static const CGFloat CELL_MIN_HEIGHT = 50.0f;
static const CGFloat CELL_MIN_WIDTH = 150.0f;
static const CGFloat CELL_MAX_WIDTH = 320.0f;
static const CGFloat CELL_MESSAGE_X_MARGIN = 26.0f;
static const CGFloat CELL_MESSAGE_Y_MARGIN = 36.0f;
static const CGFloat CELL_FONT_SIZE = 17.0f;
static const CGFloat CELL_IMAGE_HEIGHT = 100.0f;
static const CGFloat CELL_IMAGE_WIDTH = 100.0f;
static UIFont *CELL_FONT = nil;
#pragma mark - Lifecycle Functions
- (id)initWithIdentifier:(NSString*)identifier {
if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) {
[[NSBundle mainBundle] loadNibNamed:@"UIChatRoomCell"
owner:self
options:nil];
imageTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onImageClick:)];
[messageImageView addGestureRecognizer:imageTapGestureRecognizer];
[self addSubview:innerView];
[deleteButton setAlpha:0.0f];
}
return self;
}
- (void)dealloc {
[chatRoomDelegate release];
[backgroundImage release];
[innerView release];
[bubbleView release];
[messageText release];
[messageImageView release];
[deleteButton release];
[dateLabel release];
[statusImage release];
[chat release];
[downloadButton release];
[imageTapGestureRecognizer release];
[super dealloc];
}
- (void)prepareForReuse {
}
#pragma mark -
- (void)setChat:(ChatModel *)achat {
if(chat == achat) {
return;
}
if(chat != nil) {
[chat release];
chat = nil;
}
if(achat != nil) {
chat = [achat retain];
[self update];
}
}
- (void)update {
if(chat == nil) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room cell: null chat"];
return;
}
if([chat isExternalImage]) {
[messageText setHidden:TRUE];
[messageImageView setImage:nil];
[messageImageView setHidden:TRUE];
[downloadButton setHidden:FALSE];
} else if([chat isInternalImage]) {
[messageText setHidden:TRUE];
[messageImageView setImage:nil];
[messageImageView startLoading];
ChatModel *achat = chat;
[[LinphoneManager instance].photoLibrary assetForURL:[NSURL URLWithString:[chat message]] resultBlock:^(ALAsset *asset) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) {
ALAssetRepresentation* representation = [asset defaultRepresentation];
UIImage *image = [UIImage imageWithCGImage:[representation fullResolutionImage]
scale:representation.scale
orientation:(UIImageOrientation)representation.orientation];
image = [UIImage decodedImageWithImage:image];
if(achat == self->chat) { //Avoid glitch and scrolling
dispatch_async(dispatch_get_main_queue(), ^{
[messageImageView setImage:image];
[messageImageView stopLoading];
});
}
});
} failureBlock:^(NSError *error) {
[LinphoneLogger log:LinphoneLoggerError format:@"Can't read image"];
}];
[messageImageView setHidden:FALSE];
[downloadButton setHidden:TRUE];
} else {
[messageText setHidden:FALSE];
[messageText setText:[chat message]];
[messageImageView setImage:nil];
[messageImageView setHidden:TRUE];
[downloadButton setHidden:TRUE];
}
// Date
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSLocale *locale = [NSLocale currentLocale];
[dateFormatter setLocale:locale];
[dateLabel setText:[dateFormatter stringFromDate:[chat time]]];
[dateFormatter release];
if ([chat.state intValue] == LinphoneChatMessageStateInProgress) {
[statusImage setImage:[UIImage imageNamed:@"chat_message_inprogress.png"]];
statusImage.hidden = FALSE;
} else if ([chat.state intValue] == LinphoneChatMessageStateDelivered) {
[statusImage setImage:[UIImage imageNamed:@"chat_message_delivered.png"]];
statusImage.hidden = FALSE;
} else if ([chat.state intValue] == LinphoneChatMessageStateNotDelivered) {
[statusImage setImage:[UIImage imageNamed:@"chat_message_not_delivered.png"]];
statusImage.hidden = FALSE;
} else {
statusImage.hidden = TRUE;
}
}
- (void)setEditing:(BOOL)editing {
[self setEditing:editing animated:FALSE];
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
if(animated) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
}
if(editing) {
[deleteButton setAlpha:1.0f];
} else {
[deleteButton setAlpha:0.0f];
}
if(animated) {
[UIView commitAnimations];
}
}
+ (CGSize)viewSize:(ChatModel*)chat width:(int)width {
CGSize messageSize;
if(!([chat isExternalImage] || [chat isInternalImage])) {
if(CELL_FONT == nil) {
CELL_FONT = [UIFont systemFontOfSize:CELL_FONT_SIZE];
}
messageSize = [[chat message] sizeWithFont: CELL_FONT
constrainedToSize: CGSizeMake(width - CELL_MESSAGE_X_MARGIN, 10000.0f)
lineBreakMode: UILineBreakModeTailTruncation];
} else {
messageSize = CGSizeMake(CELL_IMAGE_WIDTH, CELL_IMAGE_HEIGHT);
}
messageSize.height += CELL_MESSAGE_Y_MARGIN;
if(messageSize.height < CELL_MIN_HEIGHT)
messageSize.height = CELL_MIN_HEIGHT;
messageSize.width += CELL_MESSAGE_X_MARGIN;
if(messageSize.width < CELL_MIN_WIDTH)
messageSize.width = CELL_MIN_WIDTH;
return messageSize;
}
+ (CGFloat)height:(ChatModel*)chat width:(int)width {
return [UIChatRoomCell viewSize:chat width:width].height;
}
#pragma mark - View Functions
- (void)layoutSubviews {
[super layoutSubviews];
if(chat != nil) {
// Resize inner
CGRect innerFrame;
innerFrame.size = [UIChatRoomCell viewSize:chat width:[self frame].size.width];
if([[chat direction] intValue]) { // Inverted
innerFrame.origin.x = 0.0f;
innerFrame.origin.y = 0.0f;
} else {
innerFrame.origin.x = [self frame].size.width - innerFrame.size.width;
innerFrame.origin.y = 0.0f;
}
[innerView setFrame:innerFrame];
CGRect messageFrame = [bubbleView frame];
messageFrame.origin.y = ([innerView frame].size.height - messageFrame.size.height)/2;
if([[chat direction] intValue]) { // Inverted
[backgroundImage setImage:[TUNinePatchCache imageOfSize:[backgroundImage bounds].size
forNinePatchNamed:@"chat_bubble_incoming"]];
messageFrame.origin.y += 5;
} else {
[backgroundImage setImage:[TUNinePatchCache imageOfSize:[backgroundImage bounds].size
forNinePatchNamed:@"chat_bubble_outgoing"]];
messageFrame.origin.y -= 5;
}
[bubbleView setFrame:messageFrame];
}
}
#pragma mark - Action Functions
- (IBAction)onDeleteClick:(id)event {
if(chat != NULL) {
UIView *view = [self superview];
// Find TableViewCell
if(view != nil && ![view isKindOfClass:[UITableView class]]) view = [view superview];
if(view != nil) {
UITableView *tableView = (UITableView*) view;
NSIndexPath *indexPath = [tableView indexPathForCell:self];
[[tableView dataSource] tableView:tableView commitEditingStyle:UITableViewCellEditingStyleDelete forRowAtIndexPath:indexPath];
}
}
}
- (IBAction)onDownloadClick:(id)event {
[chatRoomDelegate chatRoomStartImageDownload:[NSURL URLWithString:chat.message] userInfo:chat];
}
- (IBAction)onImageClick:(id)event {
if(![messageImageView isLoading]) {
ImageViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ImageViewController compositeViewDescription] push:TRUE], ImageViewController);
if(controller != nil) {
[controller setImage:messageImageView.image];
}
}
}
@end

View file

@ -0,0 +1,640 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1536</int>
<string key="IBDocument.SystemVersion">11E53</string>
<string key="IBDocument.InterfaceBuilderVersion">2840</string>
<string key="IBDocument.AppKitVersion">1138.47</string>
<string key="IBDocument.HIToolboxVersion">569.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1926</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUIButton</string>
<string>IBUIImageView</string>
<string>IBUILabel</string>
<string>IBUITextView</string>
<string>IBUIView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="371349661">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="579600281">
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIImageView" id="340144998">
<reference key="NSNextResponder" ref="579600281"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{5, 5}, {310, 130}}</string>
<reference key="NSSuperview" ref="579600281"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="456806949"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">chat_bubble_incoming.png</string>
</object>
</object>
<object class="IBUIView" id="456806949">
<reference key="NSNextResponder" ref="579600281"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="773132586">
<reference key="NSNextResponder" ref="456806949"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIImageView" id="546512518">
<reference key="NSNextResponder" ref="773132586"/>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{294, 104}</string>
<reference key="NSSuperview" ref="773132586"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="872109847"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<int key="IBUIContentMode">1</int>
<array key="IBUIGestureRecognizers" id="0"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUITextView" id="796660967">
<reference key="NSNextResponder" ref="773132586"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{-8, -11}, {310, 126}}</string>
<reference key="NSSuperview" ref="773132586"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="546512518"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor" id="765717609">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIClipsSubviews">YES</bool>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIScrollEnabled">NO</bool>
<bool key="IBUIShowsHorizontalScrollIndicator">NO</bool>
<bool key="IBUIShowsVerticalScrollIndicator">NO</bool>
<bool key="IBUIEditable">NO</bool>
<string key="IBUIText">They who can give up essential liberty to obtain a little temporary safety, deserve neither liberty nor safety.</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">2</int>
<bytes key="NSRGB">MC4zNTY4NjI3NTM2IDAuMzk2MDc4NDM3NiAwLjQzNTI5NDEyMTUAA</bytes>
</object>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<int key="IBUIAutocapitalizationType">2</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<int key="IBUIDataDetectorTypes">2</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIButton" id="872109847">
<reference key="NSNextResponder" ref="773132586"/>
<int key="NSvFlags">301</int>
<string key="NSFrame">{{81, 33}, {132, 37}}</string>
<reference key="NSSuperview" ref="773132586"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="859609488"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<string key="IBUINormalTitle">Download image</string>
<object class="NSColor" key="IBUIHighlightedTitleColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor" id="479423909">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="178165125">
<int key="type">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont" id="126548582">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
</array>
<string key="NSFrameSize">{294, 104}</string>
<reference key="NSSuperview" ref="456806949"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="796660967"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="765717609"/>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUILabel" id="504194589">
<reference key="NSNextResponder" ref="456806949"/>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{0, 104}, {280, 10}}</string>
<reference key="NSSuperview" ref="456806949"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="197441422"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="765717609"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">09/09/2009 at 09:09</string>
<reference key="IBUITextColor" ref="479423909"/>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">8</float>
<int key="IBUITextAlignment">2</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">9</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">9</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUIImageView" id="197441422">
<reference key="NSNextResponder" ref="456806949"/>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{284, 104}, {10, 10}}</string>
<reference key="NSSuperview" ref="456806949"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">chat_message_not_delivered.png</string>
</object>
</object>
<object class="IBUIButton" id="859609488">
<reference key="NSNextResponder" ref="456806949"/>
<int key="NSvFlags">289</int>
<string key="NSFrame">{{250, 0}, {44, 44}}</string>
<reference key="NSSuperview" ref="456806949"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="504194589"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<bool key="IBUIAdjustsImageWhenHighlighted">NO</bool>
<double key="IBUIImageEdgeInsets.top">2</double>
<double key="IBUIImageEdgeInsets.bottom">20</double>
<double key="IBUIImageEdgeInsets.left">20</double>
<double key="IBUIImageEdgeInsets.right">2</double>
<reference key="IBUINormalTitleShadowColor" ref="479423909"/>
<object class="NSCustomResource" key="IBUIHighlightedImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">list_delete_over.png</string>
</object>
<object class="NSCustomResource" key="IBUINormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">list_delete_default.png</string>
</object>
<reference key="IBUIFontDescription" ref="178165125"/>
<reference key="IBUIFont" ref="126548582"/>
</object>
</array>
<string key="NSFrame">{{13, 13}, {294, 114}}</string>
<reference key="NSSuperview" ref="579600281"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="773132586"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="765717609"/>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 140}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="340144998"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="765717609"/>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUITag">10</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="369753676">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{100, 100}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="765717609"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="111268450">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{100, 100}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="765717609"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">backgroundView</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="369753676"/>
</object>
<int key="connectionID">10</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">backgroundImage</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="340144998"/>
</object>
<int key="connectionID">11</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">selectedBackgroundView</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="111268450"/>
</object>
<int key="connectionID">13</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">deleteButton</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="859609488"/>
</object>
<int key="connectionID">19</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">dateLabel</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="504194589"/>
</object>
<int key="connectionID">24</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">innerView</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="579600281"/>
</object>
<int key="connectionID">25</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">statusImage</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="197441422"/>
</object>
<int key="connectionID">27</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">bubbleView</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="456806949"/>
</object>
<int key="connectionID">30</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">messageImageView</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="546512518"/>
</object>
<int key="connectionID">31</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">downloadButton</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="872109847"/>
</object>
<int key="connectionID">34</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">messageText</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="796660967"/>
</object>
<int key="connectionID">44</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">onDeleteClick:</string>
<reference key="source" ref="859609488"/>
<reference key="destination" ref="841351856"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">32</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">onDownloadClick:</string>
<reference key="source" ref="872109847"/>
<reference key="destination" ref="841351856"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">39</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<reference key="object" ref="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="371349661"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="579600281"/>
<array class="NSMutableArray" key="children">
<reference ref="340144998"/>
<reference ref="456806949"/>
</array>
<reference key="parent" ref="0"/>
<string key="objectName">innerView</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="369753676"/>
<reference key="parent" ref="0"/>
<string key="objectName">backgroundView</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">9</int>
<reference key="object" ref="111268450"/>
<reference key="parent" ref="0"/>
<string key="objectName">selectedBackgroundView</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="340144998"/>
<reference key="parent" ref="579600281"/>
<string key="objectName">backgroundImage</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">16</int>
<reference key="object" ref="456806949"/>
<array class="NSMutableArray" key="children">
<reference ref="504194589"/>
<reference ref="859609488"/>
<reference ref="197441422"/>
<reference ref="773132586"/>
</array>
<reference key="parent" ref="579600281"/>
<string key="objectName">bubbleView</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">18</int>
<reference key="object" ref="859609488"/>
<reference key="parent" ref="456806949"/>
<string key="objectName">deleteButton</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">22</int>
<reference key="object" ref="504194589"/>
<reference key="parent" ref="456806949"/>
<string key="objectName">timestampLabel</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">26</int>
<reference key="object" ref="197441422"/>
<reference key="parent" ref="456806949"/>
<string key="objectName">status</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">29</int>
<reference key="object" ref="773132586"/>
<array class="NSMutableArray" key="children">
<reference ref="546512518"/>
<reference ref="872109847"/>
<reference ref="796660967"/>
</array>
<reference key="parent" ref="456806949"/>
<string key="objectName">messageView</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">28</int>
<reference key="object" ref="546512518"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="773132586"/>
<string key="objectName">messageImageView</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">33</int>
<reference key="object" ref="872109847"/>
<reference key="parent" ref="773132586"/>
<string key="objectName">downloadButton</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">43</int>
<reference key="object" ref="796660967"/>
<reference key="parent" ref="773132586"/>
<string key="objectName">messageText</string>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">UIChatRoomCell</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="16.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="18.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<real value="2" key="18.IBUIButtonInspectorSelectedEdgeInsetMetadataKey"/>
<real value="0.0" key="18.IBUIButtonInspectorSelectedStateConfigurationMetadataKey"/>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="22.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="26.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="28.CustomClassName">UILoadingImageView</string>
<string key="28.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="29.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="33.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="43.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="9.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">44</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">UIChatRoomCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="actions">
<string key="onDeleteClick:">id</string>
<string key="onDownloadClick:">id</string>
<string key="onImageClick:">id</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="actionInfosByName">
<object class="IBActionInfo" key="onDeleteClick:">
<string key="name">onDeleteClick:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo" key="onDownloadClick:">
<string key="name">onDownloadClick:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo" key="onImageClick:">
<string key="name">onImageClick:</string>
<string key="candidateClassName">id</string>
</object>
</dictionary>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="backgroundImage">UIImageView</string>
<string key="bubbleView">UIView</string>
<string key="dateLabel">UILabel</string>
<string key="deleteButton">UIButton</string>
<string key="downloadButton">UIButton</string>
<string key="imageTapGestureRecognizer">UITapGestureRecognizer</string>
<string key="innerView">UIView</string>
<string key="messageImageView">UILoadingImageView</string>
<string key="messageText">UITextView</string>
<string key="statusImage">UIImageView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="backgroundImage">
<string key="name">backgroundImage</string>
<string key="candidateClassName">UIImageView</string>
</object>
<object class="IBToOneOutletInfo" key="bubbleView">
<string key="name">bubbleView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo" key="dateLabel">
<string key="name">dateLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="deleteButton">
<string key="name">deleteButton</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="downloadButton">
<string key="name">downloadButton</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="imageTapGestureRecognizer">
<string key="name">imageTapGestureRecognizer</string>
<string key="candidateClassName">UITapGestureRecognizer</string>
</object>
<object class="IBToOneOutletInfo" key="innerView">
<string key="name">innerView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo" key="messageImageView">
<string key="name">messageImageView</string>
<string key="candidateClassName">UILoadingImageView</string>
</object>
<object class="IBToOneOutletInfo" key="messageText">
<string key="name">messageText</string>
<string key="candidateClassName">UITextView</string>
</object>
<object class="IBToOneOutletInfo" key="statusImage">
<string key="name">statusImage</string>
<string key="candidateClassName">UIImageView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UIChatRoomCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UILoadingImageView</string>
<string key="superclassName">UIImageView</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">waitIndicatorView</string>
<string key="NS.object.0">UIActivityIndicatorView</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">waitIndicatorView</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">waitIndicatorView</string>
<string key="candidateClassName">UIActivityIndicatorView</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UILoadingImageView.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="chat_bubble_incoming.png">{71, 46}</string>
<string key="chat_message_not_delivered.png">{18, 17}</string>
<string key="list_delete_default.png">{45, 45}</string>
<string key="list_delete_over.png">{45, 45}</string>
</dictionary>
<string key="IBCocoaTouchPluginVersion">1926</string>
</data>
</archive>

View file

@ -0,0 +1,79 @@
/* UICompositeViewController.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "LinphoneManager.h"
#import "TPMultiLayoutViewController.h"
@interface UICompositeViewDescription: NSObject{
}
@property (retain) NSString *name;
@property (retain) NSString *content;
@property (retain) NSString *stateBar;
@property (assign) BOOL stateBarEnabled;
@property (retain) NSString *tabBar;
@property (assign) BOOL tabBarEnabled;
@property (assign) BOOL fullscreen;
@property (assign) BOOL landscapeMode;
@property (assign) BOOL portraitMode;
- (id)copy;
- (BOOL)equal:(UICompositeViewDescription*) description;
- (id)init:(NSString *)name content:(NSString *)content stateBar:(NSString*)stateBar
stateBarEnabled:(BOOL) stateBarEnabled
tabBar:(NSString*)tabBar
tabBarEnabled:(BOOL) tabBarEnabled
fullscreen:(BOOL) fullscreen
landscapeMode:(BOOL) landscapeMode
portraitMode:(BOOL) portraitMode;
@end
@protocol UICompositeViewDelegate <NSObject>
+ (UICompositeViewDescription*) compositeViewDescription;
@end
@interface UICompositeViewController : TPMultiLayoutViewController {
@private
NSMutableDictionary *viewControllerCache;
UICompositeViewDescription *currentViewDescription;
UIInterfaceOrientation currentOrientation;
}
@property (retain) CATransition *viewTransition;
@property (nonatomic, retain) IBOutlet UIView* stateBarView;
@property (nonatomic, retain) IBOutlet UIView* contentView;
@property (nonatomic, retain) IBOutlet UIView* tabBarView;
- (void)changeView:(UICompositeViewDescription *)description;
- (void)setFullScreen:(BOOL) enabled;
- (void)setStateBarHidden:(BOOL) hidden;
- (void)setToolBarHidden:(BOOL) hidden;
- (UIViewController *)getCachedController:(NSString*)name;
- (UIViewController *)getCurrentViewController;
- (UIInterfaceOrientation)currentOrientation;
- (void)clearCache:(NSArray*)exclude;
@end

View file

@ -0,0 +1,680 @@
/* UICompositeViewController.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "UICompositeViewController.h"
#import "LinphoneAppDelegate.h"
@implementation UICompositeViewDescription
@synthesize name;
@synthesize content;
@synthesize stateBar;
@synthesize stateBarEnabled;
@synthesize tabBar;
@synthesize tabBarEnabled;
@synthesize fullscreen;
@synthesize landscapeMode;
@synthesize portraitMode;
- (id)copy {
UICompositeViewDescription *copy = [UICompositeViewDescription alloc];
copy.content = self.content;
copy.stateBar = self.stateBar;
copy.stateBarEnabled = self.stateBarEnabled;
copy.tabBar = self.tabBar;
copy.tabBarEnabled = self.tabBarEnabled;
copy.fullscreen = self.fullscreen;
copy.landscapeMode = self.landscapeMode;
copy.portraitMode = self.portraitMode;
return copy;
}
- (BOOL)equal:(UICompositeViewDescription*) description {
return [self.name compare:description.name] == NSOrderedSame;
}
- (id)init:(NSString *)aname content:(NSString *)acontent stateBar:(NSString*)astateBar
stateBarEnabled:(BOOL) astateBarEnabled
tabBar:(NSString*)atabBar
tabBarEnabled:(BOOL) atabBarEnabled
fullscreen:(BOOL) afullscreen
landscapeMode:(BOOL) alandscapeMode
portraitMode:(BOOL) aportraitMode {
self.name = aname;
self.content = acontent;
self.stateBar = astateBar;
self.stateBarEnabled = astateBarEnabled;
self.tabBar = atabBar;
self.tabBarEnabled = atabBarEnabled;
self.fullscreen = afullscreen;
self.landscapeMode = alandscapeMode;
self.portraitMode = aportraitMode;
return self;
}
- (void)dealloc {
[name release];
[content release];
[stateBar release];
[tabBar release];
[super dealloc];
}
@end
@interface UICompositeViewController ()
@property (nonatomic, retain) UIViewController *stateBarViewController;
@property (nonatomic, retain) UIViewController *tabBarViewController;
@property (nonatomic, retain) UIViewController *contentViewController;
@end
@implementation UICompositeViewController
@synthesize stateBarView;
@synthesize contentView;
@synthesize tabBarView;
@synthesize tabBarViewController = _tabBarViewController;
@synthesize stateBarViewController = _stateBarViewController;
@synthesize contentViewController = _contentViewController;
@synthesize viewTransition;
#pragma mark - Lifecycle Functions
- (void)initUICompositeViewController {
viewControllerCache = [[NSMutableDictionary alloc] init];
currentOrientation = UIDeviceOrientationUnknown;
}
- (id)init{
self = [super init];
if (self) {
[self initUICompositeViewController];
}
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[self initUICompositeViewController];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self initUICompositeViewController];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.stateBarViewController release];
[self.tabBarViewController release];
[self.contentViewController release];
[contentView release];
[stateBarView release];
[tabBarView release];
[viewControllerCache release];
[viewTransition release];
[currentViewDescription release];
[super dealloc];
}
#pragma mark - Property Functions
- (UIViewController*)stateBarViewController {
return _stateBarViewController;
}
- (UIViewController*)contentViewController {
return _contentViewController;
}
- (UIViewController*)tabBarViewController {
return _tabBarViewController;
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
/* Force landscape view to match portrait view */
CGRect frame = [portraitView frame];
int height = frame.size.width;
frame.size.width = frame.size.height;
frame.size.height = height;
[landscapeView setFrame:frame];
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.contentViewController viewWillAppear:animated];
[self.tabBarViewController viewWillAppear:animated];
[self.stateBarViewController viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(orientationDidChange:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.contentViewController viewDidAppear:animated];
[self.tabBarViewController viewDidAppear:animated];
[self.stateBarViewController viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.contentViewController viewWillDisappear:animated];
[self.tabBarViewController viewWillDisappear:animated];
[self.stateBarViewController viewWillDisappear:animated];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.contentViewController viewDidDisappear:animated];
[self.tabBarViewController viewDidDisappear:animated];
[self.stateBarViewController viewDidDisappear:animated];
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
currentOrientation = toInterfaceOrientation;
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.contentViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.tabBarViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.stateBarViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.contentViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.tabBarViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.stateBarViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self update:nil tabBar:nil stateBar:nil fullscreen:nil];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
[self.contentViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
[self.tabBarViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
[self.stateBarViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(interfaceOrientation == currentOrientation)
return YES;
return NO;
}
#pragma mark - Event Functions
- (void)orientationDidChange:(NSNotification*)notif {
if([LinphoneManager isLcReady]) {
// Update rotation
UIInterfaceOrientation correctOrientation = [self getCorrectInterfaceOrientation:[[UIDevice currentDevice] orientation]];
if(currentOrientation != correctOrientation) {
[UICompositeViewController setOrientation:correctOrientation animated:currentOrientation != UIDeviceOrientationUnknown];
}
}
}
#pragma mark -
/*
Will simulate a device rotation
*/
+ (void)setOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated {
UIView *firstResponder = nil;
for(UIWindow *window in [[UIApplication sharedApplication] windows]) {
if([NSStringFromClass(window.class) isEqualToString:@"UITextEffectsWindow"] ||
[NSStringFromClass(window.class) isEqualToString:@"_UIAlertOverlayWindow"] ) {
continue;
}
UIView *view = window;
UIViewController *controller = nil;
CGRect frame = [view frame];
if([window isKindOfClass:[UILinphoneWindow class]]) {
controller = window.rootViewController;
view = controller.view;
}
UIInterfaceOrientation oldOrientation = controller.interfaceOrientation;
NSTimeInterval animationDuration = 0.0;
if(animated) {
animationDuration = 0.3f;
}
[controller willRotateToInterfaceOrientation:orientation duration:animationDuration];
if(animated) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
}
switch (orientation) {
case UIInterfaceOrientationPortrait:
[view setTransform: CGAffineTransformMakeRotation(0)];
break;
case UIInterfaceOrientationPortraitUpsideDown:
[view setTransform: CGAffineTransformMakeRotation(M_PI)];
break;
case UIInterfaceOrientationLandscapeLeft:
[view setTransform: CGAffineTransformMakeRotation(-M_PI / 2)];
break;
case UIInterfaceOrientationLandscapeRight:
[view setTransform: CGAffineTransformMakeRotation(M_PI / 2)];
break;
default:
break;
}
if([window isKindOfClass:[UILinphoneWindow class]]) {
[view setFrame:frame];
}
[controller willAnimateRotationToInterfaceOrientation:orientation duration:animationDuration];
if(animated) {
[UIView commitAnimations];
}
[controller didRotateFromInterfaceOrientation:oldOrientation];
if(firstResponder == nil) {
firstResponder = [UICompositeViewController findFirstResponder:view];
}
}
[[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:animated];
if(firstResponder) {
[firstResponder resignFirstResponder];
[firstResponder becomeFirstResponder];
}
}
+ (UIView*)findFirstResponder:(UIView*)view {
if (view.isFirstResponder) {
return view;
}
for (UIView *subView in view.subviews) {
UIView *ret = [UICompositeViewController findFirstResponder:subView];
if (ret != nil)
return ret;
}
return nil;
}
- (void)clearCache:(NSArray *)exclude {
for(NSString *key in [viewControllerCache allKeys]) {
bool remove = true;
if(exclude != nil) {
for (UICompositeViewDescription *description in exclude) {
if([key isEqualToString:description.content] ||
[key isEqualToString:description.stateBar] ||
[key isEqualToString:description.tabBar]
) {
remove = false;
break;
}
}
}
if(remove) {
[LinphoneLogger log:LinphoneLoggerLog format:@"Free cached view: %@", key];
UIViewController *vc = [viewControllerCache objectForKey:key];
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 5.0) {
[vc viewWillUnload];
}
[vc viewDidUnload];
[viewControllerCache removeObjectForKey:key];
}
}
}
- (UIInterfaceOrientation)currentOrientation {
return currentOrientation;
}
+ (void)addSubView:(UIViewController*)controller view:(UIView*)view {
if(controller != nil) {
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[controller viewWillAppear:NO];
}
[view addSubview: controller.view];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[controller viewDidAppear:NO];
}
}
}
+ (void)removeSubView:(UIViewController*)controller {
if(controller != nil) {
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[controller viewWillDisappear:NO];
}
[controller.view removeFromSuperview];
if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) {
[controller viewDidDisappear:NO];
}
}
}
- (UIViewController*)getCachedController:(NSString*)name {
UIViewController *controller = nil;
if(name != nil) {
controller = [viewControllerCache objectForKey:name];
if(controller == nil) {
controller = [[[NSClassFromString(name) alloc] init] autorelease];
[viewControllerCache setValue:controller forKey:name];
[controller view]; // Load the view
}
}
return controller;
}
- (UIInterfaceOrientation)getCorrectInterfaceOrientation:(UIDeviceOrientation)deviceOrientation {
if(currentViewDescription != nil) {
// If unknown return status bar orientation
if(deviceOrientation == UIDeviceOrientationUnknown && currentOrientation == UIDeviceOrientationUnknown) {
return [UIApplication sharedApplication].statusBarOrientation;
}
NSString* rotationPreference = [[LinphoneManager instance] lpConfigStringForKey:@"rotation_preference"];
if([rotationPreference isEqualToString:@"auto"]) {
// Don't rotate in UIDeviceOrientationFaceUp UIDeviceOrientationFaceDown
if(!UIDeviceOrientationIsPortrait(deviceOrientation) && !UIDeviceOrientationIsLandscape(deviceOrientation)) {
if(currentOrientation == UIDeviceOrientationUnknown) {
return [UIApplication sharedApplication].statusBarOrientation;
}
deviceOrientation = currentOrientation;
}
if (UIDeviceOrientationIsPortrait(deviceOrientation)) {
if ([currentViewDescription portraitMode]) {
return deviceOrientation;
} else {
return UIInterfaceOrientationLandscapeLeft;
}
}
if (UIDeviceOrientationIsLandscape(deviceOrientation)) {
if ([currentViewDescription landscapeMode]) {
return deviceOrientation;
} else {
return UIInterfaceOrientationPortrait;
}
}
} else if([rotationPreference isEqualToString:@"portrait"]) {
if ([currentViewDescription portraitMode]) {
if (UIDeviceOrientationIsPortrait(deviceOrientation)) {
return deviceOrientation;
} else {
if(UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) {
return [UIApplication sharedApplication].statusBarOrientation;
} else {
return UIInterfaceOrientationPortrait;
}
}
} else {
return UIInterfaceOrientationLandscapeLeft;
}
} else if([rotationPreference isEqualToString:@"landscape"]) {
if ([currentViewDescription landscapeMode]) {
if (UIDeviceOrientationIsLandscape(deviceOrientation)) {
return deviceOrientation;
} else {
if(UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
return [UIApplication sharedApplication].statusBarOrientation;
} else {
return UIInterfaceOrientationLandscapeLeft;
}
}
} else {
return UIInterfaceOrientationPortrait;
}
}
}
return UIInterfaceOrientationPortrait;
}
#define IPHONE_STATUSBAR_HEIGHT 20
- (void)update: (UICompositeViewDescription*) description tabBar:(NSNumber*)tabBar stateBar:(NSNumber*)stateBar fullscreen:(NSNumber*)fullscreen {
UIViewController *oldContentViewController = self.contentViewController;
UIViewController *oldStateBarViewController = self.stateBarViewController;
UIViewController *oldTabBarViewController = self.tabBarViewController;
// Copy view description
UICompositeViewDescription *oldViewDescription = nil;
if(description != nil) {
oldViewDescription = currentViewDescription;
currentViewDescription = [description copy];
// Animate only with a previous screen
if(oldViewDescription != nil && viewTransition != nil) {
[contentView.layer removeAnimationForKey:@"transition"];
[contentView.layer addAnimation:viewTransition forKey:@"transition"];
if(oldViewDescription.stateBar != currentViewDescription.stateBar ||
oldViewDescription.stateBarEnabled != currentViewDescription.stateBarEnabled ||
[stateBarView.layer animationForKey:@"transition"] != nil) {
[stateBarView.layer removeAnimationForKey:@"transition"];
[stateBarView.layer addAnimation:viewTransition forKey:@"transition"];
}
if(oldViewDescription.tabBar != currentViewDescription.tabBar ||
oldViewDescription.tabBarEnabled != currentViewDescription.tabBarEnabled ||
[tabBarView.layer animationForKey:@"transition"] != nil) {
[tabBarView.layer removeAnimationForKey:@"transition"];
[tabBarView.layer addAnimation:viewTransition forKey:@"transition"];
}
}
UIViewController *newContentViewController = [self getCachedController:description.content];
UIViewController *newStateBarViewController = [self getCachedController:description.stateBar];
UIViewController *newTabBarViewController = [self getCachedController:description.tabBar];
[UICompositeViewController removeSubView: oldContentViewController];
if(oldTabBarViewController != nil && oldTabBarViewController != newTabBarViewController) {
[UICompositeViewController removeSubView:oldTabBarViewController];
}
if(oldStateBarViewController != nil && oldStateBarViewController != newStateBarViewController) {
[UICompositeViewController removeSubView:oldStateBarViewController];
}
self.stateBarViewController = newStateBarViewController;
self.contentViewController = newContentViewController;
self.tabBarViewController = newTabBarViewController;
// Update rotation
UIInterfaceOrientation correctOrientation = [self getCorrectInterfaceOrientation:[[UIDevice currentDevice] orientation]];
if(currentOrientation != correctOrientation) {
[UICompositeViewController setOrientation:correctOrientation animated:currentOrientation!=UIDeviceOrientationUnknown];
} else {
if(oldContentViewController != newContentViewController) {
UIInterfaceOrientation oldOrientation = self.contentViewController.interfaceOrientation;
[self.contentViewController willRotateToInterfaceOrientation:correctOrientation duration:0];
[self.contentViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0];
[self.contentViewController didRotateFromInterfaceOrientation:oldOrientation];
}
if(oldTabBarViewController != newTabBarViewController) {
UIInterfaceOrientation oldOrientation = self.tabBarViewController.interfaceOrientation;
[self.tabBarViewController willRotateToInterfaceOrientation:correctOrientation duration:0];
[self.tabBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0];
[self.tabBarViewController didRotateFromInterfaceOrientation:oldOrientation];
}
if(oldStateBarViewController != newStateBarViewController) {
UIInterfaceOrientation oldOrientation = self.stateBarViewController.interfaceOrientation;
[self.stateBarViewController willRotateToInterfaceOrientation:correctOrientation duration:0];
[self.stateBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0];
[self.stateBarViewController didRotateFromInterfaceOrientation:oldOrientation];
}
}
} else {
oldViewDescription = (currentViewDescription != nil)? [currentViewDescription copy]: nil;
}
if(currentViewDescription == nil) {
return;
}
if(tabBar != nil) {
if(currentViewDescription.tabBarEnabled != [tabBar boolValue]) {
currentViewDescription.tabBarEnabled = [tabBar boolValue];
} else {
tabBar = nil; // No change = No Update
}
}
if(stateBar != nil) {
if(currentViewDescription.stateBarEnabled != [stateBar boolValue]) {
currentViewDescription.stateBarEnabled = [stateBar boolValue];
} else {
stateBar = nil; // No change = No Update
}
}
if(fullscreen != nil) {
if(currentViewDescription.fullscreen != [fullscreen boolValue]) {
currentViewDescription.fullscreen = [fullscreen boolValue];
[[UIApplication sharedApplication] setStatusBarHidden:currentViewDescription.fullscreen withAnimation:UIStatusBarAnimationSlide];
} else {
fullscreen = nil; // No change = No Update
}
} else {
[[UIApplication sharedApplication] setStatusBarHidden:currentViewDescription.fullscreen withAnimation:UIStatusBarAnimationNone];
}
// Start animation
if(tabBar != nil || stateBar != nil || fullscreen != nil) {
[UIView beginAnimations:@"resize" context:nil];
[UIView setAnimationDuration:0.35];
[UIView setAnimationBeginsFromCurrentState:TRUE];
}
CGRect contentFrame = contentView.frame;
CGRect viewFrame = [self.view frame];
// Resize StateBar
CGRect stateBarFrame = stateBarView.frame;
int origin = IPHONE_STATUSBAR_HEIGHT;
if(currentViewDescription.fullscreen)
origin = 0;
if(self.stateBarViewController != nil && currentViewDescription.stateBarEnabled) {
contentFrame.origin.y = origin + stateBarFrame.size.height;
stateBarFrame.origin.y = origin;
} else {
contentFrame.origin.y = origin;
stateBarFrame.origin.y = origin - stateBarFrame.size.height;
}
// Resize TabBar
CGRect tabFrame = tabBarView.frame;
if(self.tabBarViewController != nil && currentViewDescription.tabBarEnabled) {
tabFrame.origin.y = viewFrame.size.height;
tabFrame.origin.x = viewFrame.size.width;
tabFrame.size.height = self.tabBarViewController.view.frame.size.height;
//tabFrame.size.width = self.tabBarViewController.view.frame.size.width;
tabFrame.origin.y -= tabFrame.size.height;
tabFrame.origin.x -= tabFrame.size.width;
contentFrame.size.height = tabFrame.origin.y - contentFrame.origin.y;
for (UIView *view in self.tabBarViewController.view.subviews) {
if(view.tag == -1) {
contentFrame.size.height += view.frame.origin.y;
break;
}
}
} else {
contentFrame.size.height = viewFrame.size.height - contentFrame.origin.y;
tabFrame.origin.y = viewFrame.size.height;
}
if(currentViewDescription.fullscreen) {
contentFrame.origin.y = origin;
contentFrame.size.height = viewFrame.size.height - contentFrame.origin.y;
}
// Set frames
[contentView setFrame: contentFrame];
[self.contentViewController.view setFrame: [contentView bounds]];
[tabBarView setFrame: tabFrame];
CGRect frame = [self.tabBarViewController.view frame];
frame.size.width = [tabBarView bounds].size.width;
[self.tabBarViewController.view setFrame:frame];
[stateBarView setFrame: stateBarFrame];
frame = [self.stateBarViewController.view frame];
frame.size.width = [stateBarView bounds].size.width;
[self.stateBarViewController.view setFrame:frame];
// Commit animation
if(tabBar != nil || stateBar != nil || fullscreen != nil) {
[UIView commitAnimations];
}
// Change view
if(description != nil) {
[UICompositeViewController addSubView: self.contentViewController view:contentView];
if(oldTabBarViewController == nil || oldTabBarViewController != self.tabBarViewController) {
[UICompositeViewController addSubView: self.tabBarViewController view:tabBarView];
}
if(oldStateBarViewController == nil || oldStateBarViewController != self.stateBarViewController) {
[UICompositeViewController addSubView: self.stateBarViewController view:stateBarView];
}
}
// Dealloc old view description
if(oldViewDescription != nil) {
[oldViewDescription release];
}
}
- (void) changeView:(UICompositeViewDescription *)description {
[self view]; // Force view load
[self update:description tabBar:nil stateBar:nil fullscreen:nil];
}
- (void) setFullScreen:(BOOL) enabled {
[self update:nil tabBar:nil stateBar:nil fullscreen:[NSNumber numberWithBool:enabled]];
}
- (void) setToolBarHidden:(BOOL) hidden {
[self update:nil tabBar:[NSNumber numberWithBool:!hidden] stateBar:nil fullscreen:nil];
}
- (void) setStateBarHidden:(BOOL) hidden {
[self update:nil tabBar: nil stateBar:[NSNumber numberWithBool:!hidden] fullscreen:nil];
}
- (UIViewController *) getCurrentViewController {
return [[self.contentViewController retain] autorelease];
}
@end

View file

@ -0,0 +1,367 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11E53</string>
<string key="IBDocument.InterfaceBuilderVersion">2549</string>
<string key="IBDocument.AppKitVersion">1138.47</string>
<string key="IBDocument.HIToolboxVersion">569.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1498</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUIView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<int key="NSvFlags">301</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="481442126">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">314</int>
<string key="NSFrame">{{0, 23}, {320, 397}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="548578981"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor" id="572758541">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIAutoresizesSubviews">NO</bool>
<int key="IBUITag">1</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="256276698">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">290</int>
<string key="NSFrameSize">{320, 23}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="481442126"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="572758541"/>
<bool key="IBUIAutoresizesSubviews">NO</bool>
<int key="IBUITag">2</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="548578981">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">266</int>
<string key="NSFrame">{{0, 420}, {320, 60}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="572758541"/>
<bool key="IBUIAutoresizesSubviews">NO</bool>
<int key="IBUITag">3</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 480}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="256276698"/>
<reference key="IBUIBackgroundColor" ref="572758541"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="915565391">
<reference key="NSNextResponder"/>
<int key="NSvFlags">301</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="575003184">
<reference key="NSNextResponder" ref="915565391"/>
<int key="NSvFlags">314</int>
<string key="NSFrame">{{0, 23}, {480, 237}}</string>
<reference key="NSSuperview" ref="915565391"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="872119935"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="572758541"/>
<bool key="IBUIAutoresizesSubviews">NO</bool>
<int key="IBUITag">1</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="1051455928">
<reference key="NSNextResponder" ref="915565391"/>
<int key="NSvFlags">290</int>
<string key="NSFrameSize">{480, 23}</string>
<reference key="NSSuperview" ref="915565391"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="575003184"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="572758541"/>
<bool key="IBUIAutoresizesSubviews">NO</bool>
<int key="IBUITag">2</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="872119935">
<reference key="NSNextResponder" ref="915565391"/>
<int key="NSvFlags">266</int>
<string key="NSFrame">{{0, 260}, {480, 60}}</string>
<reference key="NSSuperview" ref="915565391"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="572758541"/>
<bool key="IBUIAutoresizesSubviews">NO</bool>
<int key="IBUITag">3</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{480, 320}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="1051455928"/>
<reference key="IBUIBackgroundColor" ref="572758541"/>
<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
<int key="IBUIInterfaceOrientation">3</int>
<int key="interfaceOrientation">3</int>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">3</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">contentView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="481442126"/>
</object>
<int key="connectionID">17</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">stateBarView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="256276698"/>
</object>
<int key="connectionID">18</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">tabBarView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="548578981"/>
</object>
<int key="connectionID">19</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">portraitView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">24</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">landscapeView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="915565391"/>
</object>
<int key="connectionID">25</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
<reference ref="481442126"/>
<reference ref="256276698"/>
<reference ref="548578981"/>
</array>
<reference key="parent" ref="0"/>
<string key="objectName">Portrait View</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">15</int>
<reference key="object" ref="481442126"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">content</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">14</int>
<reference key="object" ref="256276698"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">stateBar</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">16</int>
<reference key="object" ref="548578981"/>
<reference key="parent" ref="191373211"/>
<string key="objectName">tabBar</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">20</int>
<reference key="object" ref="915565391"/>
<array class="NSMutableArray" key="children">
<reference ref="1051455928"/>
<reference ref="575003184"/>
<reference ref="872119935"/>
</array>
<reference key="parent" ref="0"/>
<string key="objectName">Landscape View</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">22</int>
<reference key="object" ref="1051455928"/>
<reference key="parent" ref="915565391"/>
<string key="objectName">stateBar</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">23</int>
<reference key="object" ref="575003184"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="915565391"/>
<string key="objectName">content</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">21</int>
<reference key="object" ref="872119935"/>
<reference key="parent" ref="915565391"/>
<string key="objectName">tabBar</string>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">UICompositeViewController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="14.CustomClassName">UITransparentView</string>
<string key="14.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="15.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="16.CustomClassName">UITransparentView</string>
<string key="16.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="20.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="21.CustomClassName">UITransparentView</string>
<string key="21.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="22.CustomClassName">UITransparentView</string>
<string key="22.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="23.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">25</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">TPMultiLayoutViewController</string>
<string key="superclassName">UIViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="landscapeView">UIView</string>
<string key="portraitView">UIView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="landscapeView">
<string key="name">landscapeView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo" key="portraitView">
<string key="name">portraitView</string>
<string key="candidateClassName">UIView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/TPMultiLayoutViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UICompositeViewController</string>
<string key="superclassName">TPMultiLayoutViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="contentView">UIView</string>
<string key="stateBarView">UIView</string>
<string key="tabBarView">UIView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="contentView">
<string key="name">contentView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo" key="stateBarView">
<string key="name">stateBarView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo" key="tabBarView">
<string key="name">tabBarView</string>
<string key="candidateClassName">UIView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UICompositeViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UITransparentView</string>
<string key="superclassName">UIView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/UITransparentView.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1498</string>
</data>
</archive>

View file

@ -0,0 +1,33 @@
/* UIConferenceHeader.h
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import "UIPauseButton.h"
@interface UIConferenceHeader : UIViewController {
}
@property (nonatomic, retain) IBOutlet UIImageView* stateImage;
@property (nonatomic, retain) IBOutlet UIPauseButton *pauseButton;
+ (int)getHeight;
- (void)update;
@end

View file

@ -0,0 +1,69 @@
/* UIConferenceHeader.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "UIConferenceHeader.h"
#import "LinphoneManager.h"
@implementation UIConferenceHeader
@synthesize stateImage;
@synthesize pauseButton;
#pragma mark - Lifecycle Functions
- (id)init {
return [super initWithNibName:@"UIConferenceHeader" bundle:[NSBundle mainBundle]];
}
- (void)dealloc {
[stateImage release];
[pauseButton release];
[super dealloc];
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[super viewDidLoad];
// Set selected+over background: IB lack !
[pauseButton setImage:[UIImage imageNamed:@"call_state_pause_over.png"]
forState:(UIControlStateHighlighted | UIControlStateSelected)];
[pauseButton setType:UIPauseButtonType_Conference call:nil];
}
#pragma mark - Static size Functions
+ (int)getHeight {
return 50;
}
#pragma mark -
- (void)update {
[self view]; // Force view load
[stateImage setHidden:true];
[pauseButton update];
}
@end

View file

@ -1,6 +1,6 @@
/* StatusSubViewController.h
/* UIContactCell.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,20 +15,19 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#include "linphonecore.h"
*/
@interface StatusSubViewController : UIViewController {
UIImageView* image;
UIActivityIndicatorView* spinner;
UILabel* label;
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
@interface UIContactCell : UITableViewCell {
}
@property (nonatomic, retain) IBOutlet UIImageView* image;
@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* spinner;
@property (nonatomic, retain) IBOutlet UILabel* label;
@property (nonatomic, retain) IBOutlet UILabel* firstNameLabel;
@property (nonatomic, retain) IBOutlet UILabel* lastNameLabel;
@property (nonatomic, retain) IBOutlet UIImageView *avatarImage;
@property (nonatomic, assign) ABRecordRef contact;
-(BOOL) updateWithRegistrationState:(LinphoneRegistrationState)state message:(NSString*) message;
- (id)initWithIdentifier:(NSString*)identifier;
@end

View file

@ -0,0 +1,159 @@
/* UIContactCell.m
*
* Copyright (C) 2012 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "UIContactCell.h"
#import "Utils.h"
#import "FastAddressBook.h"
@implementation UIContactCell
@synthesize firstNameLabel;
@synthesize lastNameLabel;
@synthesize avatarImage;
@synthesize contact;
#pragma mark - Lifecycle Functions
- (id)initWithIdentifier:(NSString*)identifier {
if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) {
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UIContactCell"
owner:self
options:nil];
if ([arrayOfViews count] >= 1) {
[self addSubview:[[arrayOfViews objectAtIndex:0] retain]];
}
}
return self;
}
- (void) dealloc {
[firstNameLabel release];
[lastNameLabel release];
[avatarImage release];
[super dealloc];
}
#pragma mark - Property Functions
- (void)setContact:(ABRecordRef)acontact {
contact = acontact;
[self update];
}
#pragma mark -
- (void)touchUp:(id) sender {
[self setHighlighted:true animated:true];
}
- (void)touchDown:(id) sender {
[self setHighlighted:false animated:true];
}
- (void)update {
if(contact == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update contact cell: null contact"];
return;
}
CFStringRef lFirstName = ABRecordCopyValue(contact, kABPersonFirstNameProperty);
CFStringRef lLocalizedFirstName = (lFirstName != nil)?ABAddressBookCopyLocalizedLabel(lFirstName):nil;
CFStringRef lLastName = ABRecordCopyValue(contact, kABPersonLastNameProperty);
CFStringRef lLocalizedLastName = (lLastName != nil)?ABAddressBookCopyLocalizedLabel(lLastName):nil;
CFStringRef lOrganization = ABRecordCopyValue(contact, kABPersonOrganizationProperty);
CFStringRef lLocalizedOrganization = (lOrganization != nil)?ABAddressBookCopyLocalizedLabel(lOrganization):nil;
if(lLocalizedFirstName != nil)
[firstNameLabel setText: (NSString *)lLocalizedFirstName];
else
[firstNameLabel setText: @""];
if(lLocalizedLastName != nil)
[lastNameLabel setText: (NSString *)lLocalizedLastName];
else
[lastNameLabel setText: @""];
if(lLocalizedFirstName == nil && lLocalizedLastName == nil) {
[firstNameLabel setText: (NSString *)lLocalizedOrganization];
}
if(lLocalizedOrganization != nil)
CFRelease(lLocalizedOrganization);
if(lOrganization != nil)
CFRelease(lOrganization);
if(lLocalizedLastName != nil)
CFRelease(lLocalizedLastName);
if(lLastName != nil)
CFRelease(lLastName);
if(lLocalizedFirstName != nil)
CFRelease(lLocalizedFirstName);
if(lFirstName != nil)
CFRelease(lFirstName);
}
- (void)layoutSubviews {
[super layoutSubviews];
//
// Adapt size
//
CGRect firstNameFrame = [firstNameLabel frame];
CGRect lastNameFrame = [lastNameLabel frame];
// Compute firstName size
CGSize firstNameSize = [[firstNameLabel text] sizeWithFont:[firstNameLabel font]];
CGSize lastNameSize = [[lastNameLabel text] sizeWithFont:[lastNameLabel font]];
float sum = firstNameSize.width + 5 + lastNameSize.width;
float limit = self.bounds.size.width - 5 - firstNameFrame.origin.x;
if(sum >limit) {
firstNameSize.width *= limit/sum;
lastNameSize.width *= limit/sum;
}
firstNameFrame.size.width = firstNameSize.width;
lastNameFrame.size.width = lastNameSize.width;
// Compute lastName size & position
lastNameFrame.origin.x = firstNameFrame.origin.x + firstNameFrame.size.width;
if(firstNameFrame.size.width)
lastNameFrame.origin.x += 5;
[firstNameLabel setFrame: firstNameFrame];
[lastNameLabel setFrame: lastNameFrame];
}
- (void)setHighlighted:(BOOL)highlighted {
[self setHighlighted:highlighted animated:FALSE];
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
if(highlighted) {
[lastNameLabel setTextColor:[UIColor whiteColor]];
[firstNameLabel setTextColor:[UIColor whiteColor]];
} else {
[lastNameLabel setTextColor:[UIColor blackColor]];
[firstNameLabel setTextColor:[UIColor blackColor]];
}
}
@end

View file

@ -1,21 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1280</int>
<string key="IBDocument.SystemVersion">11C74</string>
<string key="IBDocument.InterfaceBuilderVersion">1938</string>
<string key="IBDocument.AppKitVersion">1138.23</string>
<string key="IBDocument.HIToolboxVersion">567.00</string>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11E53</string>
<string key="IBDocument.InterfaceBuilderVersion">2549</string>
<string key="IBDocument.AppKitVersion">1138.47</string>
<string key="IBDocument.HIToolboxVersion">569.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">933</string>
<string key="NS.object.0">1498</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUIImageView</string>
<string>IBUIActivityIndicatorView</string>
<string>IBUIView</string>
<string>IBUILabel</string>
<string>IBProxyObject</string>
<string>IBUIImageView</string>
<string>IBUILabel</string>
<string>IBUIView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
@ -33,77 +32,95 @@
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="848661322">
<object class="IBUIView" id="675878782">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIImageView" id="332800514">
<reference key="NSNextResponder" ref="848661322"/>
<int key="NSvFlags">-2147483356</int>
<string key="NSFrame">{{0, -1}, {25, 23}}</string>
<reference key="NSSuperview" ref="848661322"/>
<object class="IBUIImageView" id="275930832">
<reference key="NSNextResponder" ref="675878782"/>
<int key="NSvFlags">300</int>
<string key="NSFrame">{{6, 6}, {32, 32}}</string>
<reference key="NSSuperview" ref="675878782"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="665185352"/>
<string key="NSReuseIdentifierKey">_NS:567</string>
<reference key="NSNextKeyView" ref="505648338"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">status_gray.png</string>
</object>
</object>
<object class="IBUIActivityIndicatorView" id="665185352">
<reference key="NSNextResponder" ref="848661322"/>
<int key="NSvFlags">-2147483356</int>
<string key="NSFrame">{{0, 1}, {20, 20}}</string>
<reference key="NSSuperview" ref="848661322"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="200467549"/>
<string key="NSReuseIdentifierKey">_NS:1030</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIStyle">2</int>
</object>
<object class="IBUILabel" id="200467549">
<reference key="NSNextResponder" ref="848661322"/>
<int key="NSvFlags">-2147483356</int>
<string key="NSFrame">{{28, 0}, {280, 21}}</string>
<reference key="NSSuperview" ref="848661322"/>
<object class="IBUILabel" id="505648338">
<reference key="NSNextResponder" ref="675878782"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{46, 0}, {55, 44}}</string>
<reference key="NSSuperview" ref="675878782"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="261477247"/>
<string key="NSReuseIdentifierKey">_NS:328</string>
<object class="NSColor" key="IBUIBackgroundColor" id="497796648">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<int key="IBUITag">2</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">CARAMBA</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
<object class="IBUIAccessibilityConfiguration" key="IBUIAccessibilityConfiguration">
<string key="IBUIAccessibilityLabel">Firstname</string>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">John</string>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">1</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">17</double>
<double key="pointSize">25</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">17</double>
<double key="NSSize">25</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUILabel" id="261477247">
<reference key="NSNextResponder" ref="675878782"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{111, 0}, {200, 44}}</string>
<reference key="NSSuperview" ref="675878782"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:328</string>
<reference key="IBUIBackgroundColor" ref="497796648"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<int key="IBUITag">2</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<object class="IBUIAccessibilityConfiguration" key="IBUIAccessibilityConfiguration">
<string key="IBUIAccessibilityLabel">Lastname</string>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Doe</string>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">1</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">25</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">25</double>
<int key="NSfFlags">16</int>
</object>
</object>
</array>
<string key="NSFrameSize">{255, 23}</string>
<string key="NSFrameSize">{320, 44}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="332800514"/>
<string key="NSReuseIdentifierKey">_NS:196</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<reference key="NSNextKeyView" ref="275930832"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<reference key="IBUIBackgroundColor" ref="497796648"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
@ -111,35 +128,27 @@
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">image</string>
<string key="label">firstNameLabel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="332800514"/>
<reference key="destination" ref="505648338"/>
</object>
<int key="connectionID">8</int>
<int key="connectionID">17</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">label</string>
<string key="label">lastNameLabel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="200467549"/>
<reference key="destination" ref="261477247"/>
</object>
<int key="connectionID">9</int>
<int key="connectionID">18</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">spinner</string>
<string key="label">avatarImage</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="665185352"/>
<reference key="destination" ref="275930832"/>
</object>
<int key="connectionID">10</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="848661322"/>
</object>
<int key="connectionID">11</int>
<int key="connectionID">24</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
@ -162,91 +171,90 @@
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="848661322"/>
<int key="objectID">16</int>
<reference key="object" ref="675878782"/>
<array class="NSMutableArray" key="children">
<reference ref="665185352"/>
<reference ref="332800514"/>
<reference ref="200467549"/>
<reference ref="275930832"/>
<reference ref="505648338"/>
<reference ref="261477247"/>
</array>
<reference key="parent" ref="0"/>
<string key="objectName">status_view</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="665185352"/>
<reference key="parent" ref="848661322"/>
<string key="objectName">status_spin</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="200467549"/>
<reference key="parent" ref="848661322"/>
<string key="objectName">status_label</string>
<reference key="object" ref="505648338"/>
<reference key="parent" ref="675878782"/>
<string key="objectName">firstName</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="332800514"/>
<reference key="parent" ref="848661322"/>
<string key="objectName">status_image</string>
<int key="objectID">10</int>
<reference key="object" ref="261477247"/>
<reference key="parent" ref="675878782"/>
<string key="objectName">lastName</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">23</int>
<reference key="object" ref="275930832"/>
<reference key="parent" ref="675878782"/>
<string key="objectName">avatarImage</string>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">StatusSubViewController</string>
<string key="-1.CustomClassName">UIContactCell</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="10.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="16.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="23.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">11</int>
<int key="maxID">24</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">StatusSubViewController</string>
<string key="superclassName">UIViewController</string>
<string key="className">UIContactCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="image">UIImageView</string>
<string key="label">UILabel</string>
<string key="spinner">UIActivityIndicatorView</string>
<string key="avatarImage">UIImageView</string>
<string key="firstNameLabel">UILabel</string>
<string key="lastNameLabel">UILabel</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="image">
<string key="name">image</string>
<object class="IBToOneOutletInfo" key="avatarImage">
<string key="name">avatarImage</string>
<string key="candidateClassName">UIImageView</string>
</object>
<object class="IBToOneOutletInfo" key="label">
<string key="name">label</string>
<object class="IBToOneOutletInfo" key="firstNameLabel">
<string key="name">firstNameLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="spinner">
<string key="name">spinner</string>
<string key="candidateClassName">UIActivityIndicatorView</string>
<object class="IBToOneOutletInfo" key="lastNameLabel">
<string key="name">lastNameLabel</string>
<string key="candidateClassName">UILabel</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/StatusSubViewController.h</string>
<string key="minorKey">./Classes/UIContactCell.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="NS.key.0">status_gray.png</string>
<string key="NS.object.0">{25, 23}</string>
</object>
<string key="IBCocoaTouchPluginVersion">933</string>
<string key="IBCocoaTouchPluginVersion">1498</string>
</data>
</archive>

Some files were not shown because too many files have changed in this diff Show more