[Switch submodule branch] Merge branch 'master' into apple_store

This commit is contained in:
Guillaume BIENKOWSKI 2015-01-13 14:51:12 +01:00
commit a608a0de5d
481 changed files with 6206 additions and 65060 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@ build-*
liblinphone-sdk
liblinphone-iphone-sdk*.zip
xcuserdata/
Classes/LinphoneIOSVersion.h

1
.gitmodules vendored
View file

@ -16,6 +16,7 @@
[submodule "submodules/externals/opencore-amr"]
path = submodules/externals/opencore-amr
url = git://git.code.sf.net/p/opencore-amr/code
ignore = dirty
[submodule "submodules/msamr"]
path = submodules/msamr
url = git://git.linphone.org/msamr.git

195
.tx/config Normal file
View file

@ -0,0 +1,195 @@
[main]
host = https://www.transifex.com
lang_map = fr_CA:fr-rCA,pt_BR:pt-rBR,zh_CN:zh-rCN,zh_HK:zh-rHK,zh_TW:zh-rTW,da_DK:da-rDK,sv_SE:sv-rSE,kn_IN:kn-rIN,nl_NL:nl-rNL,en_NL:en-rNL
minimum_perc = 1
[linphone-ios.localizablestrings]
file_filter = Resources/<lang>.lproj/Localizable.strings
source_file = Resources/en.lproj/Localizable.strings
source_lang = en
[linphone-ios.aboutviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/AboutViewController.strings
source_file = Classes/Base.lproj/AboutViewController.strings
source_lang = en
[linphone-ios.chatroomviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/ChatRoomViewController.strings
source_file = Classes/Base.lproj/ChatRoomViewController.strings
source_lang = en
[linphone-ios.chatviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/ChatViewController.strings
source_file = Classes/Base.lproj/ChatViewController.strings
source_lang = en
[linphone-ios.contactdetailslabelviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/ContactDetailsLabelViewController.strings
source_file = Classes/Base.lproj/ContactDetailsLabelViewController.strings
source_lang = en
[linphone-ios.contactdetailsviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/ContactDetailsViewController.strings
source_file = Classes/Base.lproj/ContactDetailsViewController.strings
source_lang = en
[linphone-ios.contactsviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/ContactsViewController.strings
source_file = Classes/Base.lproj/ContactsViewController.strings
source_lang = en
[linphone-ios.dialerviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/DialerViewController.strings
source_file = Classes/Base.lproj/DialerViewController.strings
source_lang = en
[linphone-ios.dialerviewcontrolleripadstrings]
file_filter = Classes/<lang>.lproj/DialerViewController~ipad.strings
source_file = Classes/Base.lproj/DialerViewController~ipad.strings
source_lang = en
[linphone-ios.firstloginviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/FirstLoginViewController.strings
source_file = Classes/Base.lproj/FirstLoginViewController.strings
source_lang = en
[linphone-ios.historydetailsviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/HistoryDetailsViewController.strings
source_file = Classes/Base.lproj/HistoryDetailsViewController.strings
source_lang = en
[linphone-ios.historyviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/HistoryViewController.strings
source_file = Classes/Base.lproj/HistoryViewController.strings
source_lang = en
[linphone-ios.imageviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/ImageViewController.strings
source_file = Classes/Base.lproj/ImageViewController.strings
source_lang = en
[linphone-ios.incallviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/InCallViewController.strings
source_file = Classes/Base.lproj/InCallViewController.strings
source_lang = en
[linphone-ios.incomingcallviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/IncomingCallViewController.strings
source_file = Classes/Base.lproj/IncomingCallViewController.strings
source_lang = en
[linphone-ios.incomingcallviewcontrolleripadstrings]
file_filter = Classes/<lang>.lproj/IncomingCallViewController~ipad.strings
source_file = Classes/Base.lproj/IncomingCallViewController~ipad.strings
source_lang = en
[linphone-ios.wizardviewcontrollerstrings]
file_filter = Classes/<lang>.lproj/WizardViewController.strings
source_file = Classes/Base.lproj/WizardViewController.strings
source_lang = en
[linphone-ios.wizardviewcontrolleripadstrings]
file_filter = Classes/<lang>.lproj/WizardViewController~ipad.strings
source_file = Classes/Base.lproj/WizardViewController~ipad.strings
source_lang = en
[linphone-ios.wizardviewsstrings]
file_filter = Classes/<lang>.lproj/WizardViews.strings
source_file = Classes/Base.lproj/WizardViews.strings
source_lang = en
[linphone-ios.uicallbarstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UICallBar.strings
source_file = Classes/LinphoneUI/Base.lproj/UICallBar.strings
source_lang = en
[linphone-ios.uicallbaripadstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UICallBar~ipad.strings
source_file = Classes/LinphoneUI/Base.lproj/UICallBar~ipad.strings
source_lang = en
[linphone-ios.uicallcellstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UICallCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UICallCell.strings
source_lang = en
[linphone-ios.uichatcellstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UIChatCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIChatCell.strings
source_lang = en
[linphone-ios.uichatroomcellstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UIChatRoomCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIChatRoomCell.strings
source_lang = en
[linphone-ios.uiconferenceheaderstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UIConferenceHeader.strings
source_file = Classes/LinphoneUI/Base.lproj/UIConferenceHeader.strings
source_lang = en
[linphone-ios.uicontactcellstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UIContactCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIContactCell.strings
source_lang = en
[linphone-ios.uicontactdetailsfooterstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UIContactDetailsFooter.strings
source_file = Classes/LinphoneUI/Base.lproj/UIContactDetailsFooter.strings
source_lang = en
[linphone-ios.uicontactdetailsheaderstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UIContactDetailsHeader.strings
source_file = Classes/LinphoneUI/Base.lproj/UIContactDetailsHeader.strings
source_lang = en
[linphone-ios.uihistorycellstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UIHistoryCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIHistoryCell.strings
source_lang = en
[linphone-ios.uimainbarstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UIMainBar.strings
source_file = Classes/LinphoneUI/Base.lproj/UIMainBar.strings
source_lang = en
[linphone-ios.uimainbaripadstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UIMainBar~ipad.strings
source_file = Classes/LinphoneUI/Base.lproj/UIMainBar~ipad.strings
source_lang = en
[linphone-ios.uistatebarstrings]
file_filter = Classes/LinphoneUI/<lang>.lproj/UIStateBar.strings
source_file = Classes/LinphoneUI/Base.lproj/UIStateBar.strings
source_lang = en

View file

@ -18,9 +18,9 @@
*/
#import "AboutViewController.h"
#include "ConsoleViewController.h"
#import "LinphoneManager.h"
#include "linphone/lpconfig.h"
#include "LinphoneIOSVersion.h"
@implementation AboutViewController
@ -74,8 +74,10 @@
[linphoneLabel setText:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]];
[linphoneIphoneVersionLabel setText:[NSString stringWithFormat:@"%@ iPhone %@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]
,[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]];
[linphoneIphoneVersionLabel setText:[NSString stringWithFormat:@"%@ iPhone %@",
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"],
[NSString stringWithUTF8String:LINPHONE_IOS_VERSION]]
];
[linphoneCoreVersionLabel setText:[NSString stringWithFormat:@"%@ Core %s", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"], linphone_core_get_version()]];
@ -126,18 +128,7 @@ static UICompositeViewDescription *compositeDescription = nil;
}
+ (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;
}

Binary file not shown.

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1072" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AboutViewController">
@ -21,6 +21,8 @@
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" id="62">
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<inset key="contentInset" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
</scrollView>
@ -80,9 +82,16 @@
</webView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
</view>
</objects>
<resources>
<image name="linphone_logo.png" width="512" height="512"/>
</resources>
</document>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -110,7 +110,7 @@
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="89"/>
</connections>
</button>
<searchBar contentMode="redraw" id="5jE-oF-d45" userLabel="searchBar">
<searchBar contentMode="redraw" showsCancelButton="YES" id="5jE-oF-d45" userLabel="searchBar">
<rect key="frame" x="0.0" y="44" width="320" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<textInputTraits key="textInputTraits"/>

Binary file not shown.

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6245" systemVersion="13F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="13F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1536" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6238"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="DialerViewController">
@ -32,20 +32,20 @@
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="171">
<rect key="frame" x="0.0" y="0.0" width="320" height="374"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
<subviews>
<view clipsSubviews="YES" contentMode="scaleToFill" id="178" userLabel="dialer">
<rect key="frame" x="0.0" y="0.0" width="320" height="80"/>
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="dialer_address_background.png" id="179" userLabel="background">
<rect key="frame" x="0.0" y="0.0" width="320" height="80"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</imageView>
<textField opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Enter SIP address or phone number..." adjustsFontSizeToFit="NO" minimumFontSize="15" id="4" userLabel="addressField" customClass="UIAddressTextField">
<rect key="frame" x="5" y="0.0" width="310" height="60"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<accessibility key="accessibilityConfiguration" label="Enter a address"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
@ -61,7 +61,7 @@
</view>
<view contentMode="scaleToFill" id="180" userLabel="pad">
<rect key="frame" x="0.0" y="58" width="320" height="260"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="38" userLabel="1" customClass="UIDigitButtonLongVoiceMail">
<rect key="frame" x="0.0" y="11" width="107" height="54"/>
@ -79,7 +79,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="37" userLabel="2" customClass="UIDigitButton">
<rect key="frame" x="107" y="11" width="106" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="2"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_two_default.png">
@ -92,7 +92,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="29" userLabel="3" customClass="UIDigitButton">
<rect key="frame" x="213" y="11" width="107" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="3"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_three_default.png">
@ -105,7 +105,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="30" userLabel="4" customClass="UIDigitButton">
<rect key="frame" x="0.0" y="73" width="107" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="4"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_four_default.png">
@ -118,7 +118,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="31" userLabel="5" customClass="UIDigitButton">
<rect key="frame" x="108" y="73" width="106" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="5"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_five_default.png">
@ -131,7 +131,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="33" userLabel="6" customClass="UIDigitButton">
<rect key="frame" x="213" y="73" width="107" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="6"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_six_default.png">
@ -144,7 +144,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="34" userLabel="7" customClass="UIDigitButton">
<rect key="frame" x="0.0" y="135" width="107" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="7"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_seven_default.png">
@ -157,7 +157,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="35" userLabel="8" customClass="UIDigitButton">
<rect key="frame" x="107" y="135" width="106" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="8"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_eight_default.png">
@ -170,7 +170,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="36" userLabel="9" customClass="UIDigitButton">
<rect key="frame" x="213" y="135" width="107" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="9"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_nine_default.png">
@ -183,7 +183,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="39" userLabel="*" customClass="UIDigitButton">
<rect key="frame" x="0.0" y="197" width="107" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Star"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_star_default.png">
@ -196,7 +196,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="40" userLabel="0" customClass="UIDigitButtonLongPlus">
<rect key="frame" x="107" y="197" width="106" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="0"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_zero_default.png">
@ -209,7 +209,7 @@
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="41" userLabel="#" customClass="UIDigitButton">
<rect key="frame" x="213" y="197" width="107" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Sharp"/>
<fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
<state key="normal" image="numpad_sharp_default.png">
@ -224,12 +224,12 @@
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="182" userLabel="toolBar">
<rect key="frame" x="0.0" y="305" width="320" height="69"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<rect key="frame" x="0.0" y="305" width="320" height="68.999999433755875"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="222" userLabel="addContactButton">
<rect key="frame" x="0.0" y="0.0" width="106" height="69"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Add to contact"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="add_contact_default.png">
@ -243,7 +243,7 @@
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="183" userLabel="backButton">
<rect key="frame" x="0.0" y="0.0" width="106" height="69"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="back_default.png">
@ -257,7 +257,7 @@
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="224" userLabel="callButton" customClass="UICallButton">
<rect key="frame" x="106" y="0.0" width="108" height="69"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Call"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_default.png">
@ -271,7 +271,7 @@
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="184" userLabel="addCallButton" customClass="UICallButton">
<rect key="frame" x="106" y="0.0" width="108" height="69"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Add call"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="add_call_default.png">
@ -285,7 +285,7 @@
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="236" userLabel="transferButton" customClass="UITransferButton">
<rect key="frame" x="106" y="0.0" width="108" height="69"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Transfer call"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="transfer_call_default.png">
@ -299,7 +299,7 @@
</button>
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="185" userLabel="backspaceButton" customClass="UIEraseButton">
<rect key="frame" x="214" y="0.0" width="106" height="69"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Backspace"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="backspace_default.png">

Binary file not shown.

Binary file not shown.

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1072" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="HistoryDetailsViewController">
@ -36,7 +36,7 @@
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="9" userLabel="backButton">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="9" userLabel="backButton" customClass="UIButtonShrinkable">
<rect key="frame" x="0.0" y="0.0" width="160" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
@ -53,7 +53,7 @@
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="11"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="50" userLabel="addButton">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="50" userLabel="addButton" customClass="UIButtonShrinkable">
<rect key="frame" x="160" y="0.0" width="160" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Add to contact"/>
@ -218,7 +218,7 @@
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="37" userLabel="callButton">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="37" userLabel="callButton" customClass="UIButtonShrinkable">
<rect key="frame" x="33" y="268" width="255" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Callback"/>
@ -233,7 +233,7 @@
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="65"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="59" userLabel="messageButton">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="59" userLabel="messageButton" customClass="UIButtonShrinkable">
<rect key="frame" x="33" y="326" width="255" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Send message"/>
@ -250,6 +250,8 @@
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
</view>
</objects>
<resources>
@ -263,4 +265,9 @@
<image name="history_details_back_over.png" width="320" height="88"/>
<image name="toolsbar_background.png" width="5" height="88"/>
</resources>
</document>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -36,8 +36,8 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleAspectFill" id="127" userLabel="preview">
<rect key="frame" x="216" y="323.99999987758844" width="96" height="128"/>
<view contentMode="scaleAspectFit" id="127" userLabel="preview">
<rect key="frame" x="216.00000029802322" y="323.99999984561953" width="96" height="128"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="5053" systemVersion="13C64" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1536" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="WizardViewController">
@ -20,6 +20,7 @@
<outlet property="provisionedPassword" destination="ClH-fT-a8N" id="h61-p1-4qG"/>
<outlet property="provisionedUsername" destination="MyR-eX-QTa" id="gmr-FI-hpH"/>
<outlet property="remoteProvisioningButton" destination="Kbn-dL-C5h" id="PPk-DJ-nEb"/>
<outlet property="transportChooser" destination="Nrv-SM-lMf" id="7iR-aG-eQf"/>
<outlet property="validateAccountView" destination="101" id="112"/>
<outlet property="welcomeView" destination="21" id="28"/>
</connections>
@ -366,6 +367,16 @@
<action selector="onSignInExternalClick:" destination="-1" eventType="touchUpInside" id="115"/>
</connections>
</button>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="0" id="Nrv-SM-lMf">
<rect key="frame" x="40" y="273" width="240" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<segments>
<segment title="UDP"/>
<segment title="TCP"/>
<segment title="TLS"/>
</segments>
<color key="tintColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
</segmentedControl>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>

View file

@ -4,18 +4,18 @@
*
* 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
* 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"
@ -34,7 +34,7 @@
- (void)dealloc {
[chatRoomDelegate release];
[self clearMessageList];
[super dealloc];
}
@ -47,6 +47,7 @@
// chatRoom = NULL;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self reloadData];
}
@ -119,7 +120,7 @@
if(messageList == nil || chatRoom == nil) {
return;
}
int index = -1;
int count = ms_list_size(messageList);
// Find first unread & set all entry read
@ -135,11 +136,11 @@
}
linphone_chat_room_mark_as_read(chatRoom);
// Scroll to unread
if(index >= 0) {
[self.tableView.layer removeAllAnimations];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]
atScrollPosition:UITableViewScrollPositionTop
animated:animated];
}
@ -169,7 +170,7 @@
cell = [[[UIChatRoomCell alloc] initWithIdentifier:kCellId] autorelease];
}
LinphoneChatMessage* chat = ms_list_nth_data(self->messageList, [indexPath row]);
LinphoneChatMessage* chat = ms_list_nth_data(self->messageList, (int)[indexPath row]);
[cell setChatMessage:chat];
[cell setChatRoomDelegate:chatRoomDelegate];
return cell;
@ -181,7 +182,7 @@
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
LinphoneChatMessage *chat = ms_list_nth_data(self->messageList, [indexPath row]);
LinphoneChatMessage *chat = ms_list_nth_data(self->messageList, (int)[indexPath row]);
if( chat ){
linphone_chat_room_delete_message(chatRoom, chat);
@ -203,7 +204,7 @@
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
LinphoneChatMessage* message = ms_list_nth_data(self->messageList, [indexPath row]);
LinphoneChatMessage* message = ms_list_nth_data(self->messageList, (int)[indexPath row]);
return [UIChatRoomCell height:message width:[self.view frame].size.width];
}

View file

@ -49,6 +49,7 @@
@property (nonatomic, retain) IBOutlet UIImageView *messageBackgroundImage;
@property (nonatomic, retain) IBOutlet UIImageView *transferBackgroundImage;
@property (nonatomic, retain) IBOutlet UITapGestureRecognizer *listTapGestureRecognizer;
@property (nonatomic, retain) IBOutlet UISwipeGestureRecognizer *listSwipeGestureRecognizer;
@property (retain, nonatomic) IBOutlet UILabel *composeLabel;
@property (retain, nonatomic) IBOutlet UIView *composeIndicatorView;

View file

@ -4,18 +4,18 @@
*
* 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
* 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"
@ -42,6 +42,7 @@
@synthesize messageBackgroundImage;
@synthesize transferBackgroundImage;
@synthesize listTapGestureRecognizer;
@synthesize listSwipeGestureRecognizer;
@synthesize pictureButton;
@synthesize imageTransferProgressBar;
@synthesize cancelTransferButton;
@ -57,6 +58,7 @@
self->chatRoom = NULL;
self->imageSharing = NULL;
self->listTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onListTap:)];
self.listSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onListSwipe:)];
self->imageQualities = [[OrderedDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithFloat:0.9], NSLocalizedString(@"Maximum", nil),
[NSNumber numberWithFloat:0.5], NSLocalizedString(@"Average", nil),
@ -78,17 +80,18 @@
[messageView release];
[messageBackgroundImage release];
[transferBackgroundImage release];
[listTapGestureRecognizer release];
[listSwipeGestureRecognizer release];
[transferView release];
[pictureButton release];
[imageTransferProgressBar release];
[cancelTransferButton release];
[imageQualities release];
[waitView release];
[composeLabel release];
[composeIndicatorView release];
[super dealloc];
@ -101,10 +104,10 @@ static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if(compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:@"ChatRoom"
content:@"ChatRoomViewController"
stateBar:nil
stateBarEnabled:false
compositeDescription = [[UICompositeViewDescription alloc] init:@"ChatRoom"
content:@"ChatRoomViewController"
stateBar:nil
stateBarEnabled:false
tabBar:/*@"UIMainBar"*/nil
tabBarEnabled:false /*to keep room for chat*/
fullscreen:false
@ -120,13 +123,13 @@ static UICompositeViewDescription *compositeDescription = nil;
- (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;
@ -135,10 +138,14 @@ static UICompositeViewDescription *compositeDescription = nil;
messageField.internalTextView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 10);
messageField.backgroundColor = [UIColor clearColor];
[sendButton setEnabled:FALSE];
[tableController.tableView addGestureRecognizer:listTapGestureRecognizer];
[listTapGestureRecognizer setEnabled:FALSE];
listSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[tableController.tableView addGestureRecognizer:listSwipeGestureRecognizer];
listSwipeGestureRecognizer.enabled = TRUE;
[tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4
[tableController.tableView setBackgroundView:nil];
}
@ -151,29 +158,25 @@ static UICompositeViewDescription *compositeDescription = nil;
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textReceivedEvent:)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textReceivedEvent:)
name:kLinphoneTextReceived
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onMessageChange:)
name:UITextViewTextDidChangeNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onMessageChange:)
name:UITextViewTextDidChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textComposeEvent:)
name:kLinphoneTextComposeEvent
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(coreUpdateEvent:)
name:kLinphoneCoreUpdate
object:nil];
if([tableController isEditing])
[tableController setEditing:FALSE animated:FALSE];
[editButton setOff];
@ -181,8 +184,8 @@ static UICompositeViewDescription *compositeDescription = nil;
[messageBackgroundImage setImage:[TUNinePatchCache imageOfSize:[messageBackgroundImage bounds].size
forNinePatchNamed:@"chat_message_background"]];
BOOL fileSharingEnabled = [[LinphoneManager instance] lpConfigStringForKey:@"sharing_server_preference"] != NULL
BOOL fileSharingEnabled = [[LinphoneManager instance] lpConfigStringForKey:@"sharing_server_preference"] != NULL
&& [[[LinphoneManager instance] lpConfigStringForKey:@"sharing_server_preference"] length]>0;
[pictureButton setEnabled:fileSharingEnabled];
[waitView setHidden:TRUE];
@ -190,11 +193,11 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if(imageSharing) {
[imageSharing cancel];
}
[messageField resignFirstResponder];
[self setComposingVisible:FALSE withDelay:0]; // will hide the "user is composing.." message
@ -202,22 +205,19 @@ static UICompositeViewDescription *compositeDescription = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
name:UIKeyboardWillHideNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneTextReceived
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UITextViewTextDidChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneCoreUpdate
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kLinphoneTextComposeEvent
object:nil];
@ -236,11 +236,12 @@ static UICompositeViewDescription *compositeDescription = nil;
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
[TUNinePatchCache flushCache]; // will remove any images cache (freeing any cached but unused images)
}
#pragma mark -
#pragma mark -
- (void)setChatRoom:(LinphoneChatRoom *)room {
self->chatRoom = room;
@ -264,7 +265,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room header: null contact"];
return;
}
NSString *displayName = nil;
UIImage *image = nil;
const LinphoneAddress* linphoneAddress = linphone_chat_room_get_peer_address(chatRoom);
@ -282,40 +283,36 @@ static UICompositeViewDescription *compositeDescription = nil;
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];
}
// 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];
}
static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud) {
ChatRoomViewController* thiz = (ChatRoomViewController*)ud;
const char*text = linphone_chat_message_get_text(msg);
[LinphoneLogger log:LinphoneLoggerLog
[LinphoneLogger log:LinphoneLoggerLog
format:@"Delivery status for [%s] is [%s]",text,linphone_chat_message_state_to_string(state)];
[thiz.tableController updateChatEntry:msg];
}
- (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(chatRoom == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot send message: No chatroom"];
return FALSE;
@ -413,13 +410,13 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
newTableFrame.size.height += newComposingFrame.size.height;
newComposingFrame.origin.y = keyboardFrame.origin.y;
}
composingVisible = visible;
[UIView animateWithDuration:delay
animations:^{
self.tableController.tableView.frame = newTableFrame;
self.composeIndicatorView.frame = newComposingFrame;
}
completion:^(BOOL finished) {
composingVisible = visible;
[self.tableController scrollToBottom:TRUE];
}];
}
@ -427,12 +424,6 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
#pragma mark - Event Functions
- (void)coreUpdateEvent:(NSNotification*)notif {
if(![LinphoneManager isLcReady]) {
chatRoom = NULL;
}
}
- (void)textReceivedEvent:(NSNotification *)notif {
LinphoneAddress * from = [[[notif userInfo] objectForKey:@"from_address"] pointerValue];
LinphoneChatRoom* room = [[notif.userInfo objectForKey:@"room"] pointerValue];
@ -448,8 +439,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
if(fromStr && cr_from_string ) {
if(strcasecmp(cr_from_string, fromStr) == 0) {
if (![[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
|| [UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) {
linphone_chat_room_mark_as_read(room);
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
}
@ -492,13 +482,13 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
- (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];
@ -508,11 +498,11 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
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"]];
// if we're showing the compose message, update it position
@ -549,6 +539,9 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
- (IBAction)onListTap:(id)sender {
[messageField resignFirstResponder];
}
- (IBAction)onListSwipe:(id)sender {
[self onBackClick:sender];
}
- (IBAction)onMessageChange:(id)sender {
if([[messageField text] length] > 0) {
@ -560,7 +553,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
- (IBAction)onPictureClick:(id)event {
[messageField resignFirstResponder];
void (^block)(UIImagePickerControllerSourceType) = ^(UIImagePickerControllerSourceType type) {
UICompositeViewDescription *description = [ImagePickerViewController compositeViewDescription];
ImagePickerViewController *controller;
@ -571,23 +564,23 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
}
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:^(){
@ -600,7 +593,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
}];
}
[sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel",nil) block:nil];
[sheet showInView:[PhoneMainView instance].view];
}
@ -679,7 +672,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
- (void)imageSharingUploadDone:(ImageSharing*)aimageSharing url:(NSURL*)url{
[self sendMessage:nil withExterlBodyUrl:url withInternalURL:[aimageSharing userInfo] ];
[messageView setHidden:FALSE];
[transferView setHidden:TRUE];
imageSharing = nil;
@ -688,7 +681,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
- (void)imageSharingDownloadDone:(ImageSharing*)aimageSharing image:(UIImage *)image {
[messageView setHidden:FALSE];
[transferView setHidden:TRUE];
__block LinphoneChatMessage *chat = (LinphoneChatMessage *)[(NSValue*)[imageSharing userInfo] pointerValue];
[[LinphoneManager instance].photoLibrary writeImageToSavedPhotosAlbum:image.CGImage
orientation:(ALAssetOrientation)[image imageOrientation]
@ -724,7 +717,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
[controller.popoverController dismissPopoverAnimated:TRUE];
}
}
NSURL *url = [info valueForKey:UIImagePickerControllerReferenceURL];
[self chooseImageQuality:image url:url];
}
@ -733,62 +726,60 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
#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];
CGFloat composeIndicatorCompensation = composingVisible ? composeIndicatorView.frame.size.height : 0.0f;
// 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];
[headerView setAlpha:1.0];
}
// 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 - composeIndicatorCompensation;
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];
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
CGFloat composeIndicatorCompensation = composingVisible ? composeIndicatorView.frame.size.height : 0.0f;
// 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 back into place (was hidden before)
{
CGRect headerFrame = [headerView frame];
headerFrame.origin.y = 0;
[headerView setFrame:headerFrame];
[headerView setAlpha:1.0];
}
// 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 - composeIndicatorCompensation;
[tableController.view setFrame:tableFrame];
// Scroll to bottom
NSInteger lastSection = [tableController.tableView numberOfSections] - 1;
if(lastSection >= 0) {
NSInteger lastRow = [tableController.tableView numberOfRowsInSection:lastSection] - 1;
if(lastRow >=0) {
[tableController.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:lastRow inSection:lastSection]
atScrollPosition:UITableViewScrollPositionBottom
animated:FALSE];
}
}
}
} completion:^(BOOL finished) {}];
}
- (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];
CGFloat composeIndicatorCompensation = composingVisible ? composeIndicatorView.frame.size.height : 0.0f;
[UIView beginAnimations:@"resize" context:nil];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:TRUE];
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
if(([[UIDevice currentDevice].systemVersion floatValue] < 8) &&
UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
@ -797,46 +788,47 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
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];
[headerView setAlpha:0.0];
}
// 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 - composeIndicatorCompensation;
[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];
// 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];
}
}
[UIView commitAnimations];
// Move header view
{
CGRect headerFrame = [headerView frame];
headerFrame.origin.y = -headerFrame.size.height;
[headerView setFrame:headerFrame];
[headerView setAlpha:0.0];
}
// 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 - composeIndicatorCompensation;
[tableController.view setFrame:tableFrame];
}
// Scroll
NSInteger lastSection = [tableController.tableView numberOfSections] - 1;
if(lastSection >= 0) {
NSInteger lastRow = [tableController.tableView numberOfRowsInSection:lastSection] - 1;
if(lastRow >=0) {
[tableController.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:lastRow inSection:lastSection]
atScrollPosition:UITableViewScrollPositionBottom
animated:FALSE];
}
}
} completion:^(BOOL finished) {}];
}
@end

View file

@ -50,10 +50,8 @@
#pragma mark -
static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRoom *elem){
MSList* new_history = linphone_chat_room_get_history(to_insert, 1);
LinphoneChatMessage* last_new_message = new_history? new_history->data : NULL;
MSList* elem_history = linphone_chat_room_get_history(elem, 1);
LinphoneChatMessage* last_elem_message = elem_history?elem_history->data:NULL;
LinphoneChatMessage* last_new_message = linphone_chat_room_get_user_data(to_insert);
LinphoneChatMessage* last_elem_message = linphone_chat_room_get_user_data(elem);
if( last_new_message && last_elem_message ){
time_t new = linphone_chat_message_get_time(last_new_message);
@ -70,13 +68,36 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
MSList* iter = unsorted;
while (iter) {
sorted = ms_list_insert_sorted(sorted, iter->data, (MSCompareFunc)sorted_history_comparison);
// store last message in user data
MSList* history = linphone_chat_room_get_history(iter->data, 1);
LinphoneChatMessage* last_msg = history? history->data : NULL;
if( last_msg ){
linphone_chat_room_set_user_data(iter->data, linphone_chat_message_ref(last_msg));
}
ms_list_free_with_data(history, (void (*)(void *))linphone_chat_message_unref);
sorted = ms_list_insert_sorted(sorted,
linphone_chat_room_ref(iter->data),
(MSCompareFunc)sorted_history_comparison);
iter = iter->next;
}
return sorted;
}
static void chatTable_free_chatrooms(void *data){
LinphoneChatMessage* lastMsg = linphone_chat_room_get_user_data(data);
if( lastMsg ){
linphone_chat_message_unref(linphone_chat_room_get_user_data(data));
linphone_chat_room_set_user_data(data, NULL);
}
linphone_chat_room_unref(data);
}
- (void)loadData {
if( data != NULL ){
ms_list_free_with_data(data, chatTable_free_chatrooms);
}
data = [self sortChatRooms];
[[self tableView] reloadData];
}
@ -97,14 +118,13 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
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 setChatRoom:(LinphoneChatRoom*)ms_list_nth_data(data, [indexPath row])];
[cell setChatRoom:(LinphoneChatRoom*)ms_list_nth_data(data, (int)[indexPath row])];
return cell;
}
@ -114,7 +134,7 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
LinphoneChatRoom *chatRoom = (LinphoneChatRoom*)ms_list_nth_data(data, [indexPath row]);
LinphoneChatRoom *chatRoom = (LinphoneChatRoom*)ms_list_nth_data(data, (int)[indexPath row]);
// Go to ChatRoom view
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
@ -135,14 +155,15 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
if(editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
LinphoneChatRoom *chatRoom = (LinphoneChatRoom*)ms_list_nth_data(data, [indexPath row]);
LinphoneChatRoom *chatRoom = (LinphoneChatRoom*)ms_list_nth_data(data, (int)[indexPath row]);
linphone_chat_room_delete_history(chatRoom);
linphone_chat_room_destroy(chatRoom);
data = linphone_core_get_chat_rooms([LinphoneManager getLc]);
linphone_chat_room_unref(chatRoom);
// will force a call to [self loadData]
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
}
}

View file

@ -67,7 +67,6 @@
if([tableController isEditing])
[tableController setEditing:FALSE animated:FALSE];
[editButton setOff];
[tableController loadData];
}
- (void)viewWillDisappear:(BOOL)animated {

View file

@ -1,28 +0,0 @@
/* ConsoleViewController.h
*
* Copyright (C) 2010 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"
@interface ConsoleViewController : UIViewController<UICompositeViewDelegate, UIWebViewDelegate> {
}
@property (nonatomic, retain) IBOutlet UIWebView* logsView;
@end

View file

@ -1,153 +0,0 @@
/*ConsoleViewController.h
*
* Copyright (C) 2010 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 "ConsoleViewController.h"
@implementation ConsoleViewController
@synthesize logsView;
#pragma mark - Lifecycle Functions
- (id)init {
return [super initWithNibName:@"ConsoleViewController" bundle:[NSBundle mainBundle]];
}
- (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

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1072" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ConsoleViewController">
<connections>
<outlet property="logsView" destination="18" id="19"/>
<outlet property="view" destination="4" id="14"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="4">
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<webView contentMode="scaleToFill" id="18" userLabel="logsView">
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<dataDetectorType key="dataDetectorTypes"/>
</webView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</objects>
</document>

View file

@ -38,6 +38,7 @@
@property (nonatomic, retain) IBOutlet UIContactDetailsFooter *footerController;
- (BOOL)isValid;
- (void)addPhoneField:(NSString*)number;
- (void)addSipField:(NSString*)address;
- (void)addEmailField:(NSString*)address;

View file

@ -141,7 +141,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
[contactDetailsDelegate onModification:nil];
}
- (NSMutableArray*)getSectionData:(int)section {
- (NSMutableArray*)getSectionData:(NSInteger)section {
if(contactSections[section] == ContactSections_Number) {
return [dataCache objectAtIndex:0];
} else if(contactSections[section] == ContactSections_Sip) {
@ -156,6 +156,15 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
return nil;
}
- (ABPropertyID)propertyIDForSection:(ContactSections_e)section {
switch (section) {
case ContactSections_Sip: return kABPersonInstantMessageProperty;
case ContactSections_Number: return kABPersonPhoneProperty;
case ContactSections_Email: return kABPersonEmailProperty;
default: return kABInvalidPropertyType;
}
}
+ (NSString*)localizeLabel:(NSString*)str {
CFStringRef lLocalizedLabel = ABAddressBookCopyLocalizedLabel((CFStringRef) str);
NSString * retStr = [NSString stringWithString:(NSString*) lLocalizedLabel];
@ -279,8 +288,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceValueAtIndex(lMap, lDict, index);
} else {
CFStringRef label = (CFStringRef)[labelArray objectAtIndex:0];
CFStringRef label = (CFStringRef)[labelArray objectAtIndex:0];
ABMultiValueAddValueAndLabel(lMap, lDict, label, &index);
}
@ -411,37 +419,26 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
- (void)removeEmptyEntry:(UITableView*)tableview section:(NSInteger)section animated:(BOOL)animated {
NSMutableArray *sectionDict = [self getSectionData:section];
int row = [sectionDict count] - 1;
NSInteger 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);
ABPropertyID property = [self propertyIDForSection:contactSections[section]];
if( property != kABInvalidPropertyType ){
ABMultiValueRef lMap = ABRecordCopyValue(contact, property);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFTypeRef valueRef = ABMultiValueCopyValueAtIndex(lMap, index);
CFTypeRef toRelease = valueRef;
if (property == kABPersonInstantMessageProperty ) {
// when we query the instanteMsg property we get a dictionary instead of a value
valueRef = CFDictionaryGetValue(valueRef, kABPersonInstantMessageUsernameKey);
}
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);
} else if(contactSections[section] == ContactSections_Email) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonEmailProperty);
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(toRelease);
CFRelease(lMap);
}
}
if(contactDetailsDelegate != nil) {
@ -451,32 +448,19 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
- (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);
Entry *entry = [sectionArray objectAtIndex:[indexPath row]];
ABPropertyID property = [self propertyIDForSection:contactSections[indexPath.section]];
if( property != kABInvalidPropertyType ){
ABMultiValueRef lcMap = ABRecordCopyValue(contact, property);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
NSInteger 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);
} else if(contactSections[[indexPath section]] == ContactSections_Email) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonEmailProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueRemoveValueAndLabelAtIndex(lMap, index);
ABRecordSetValue(contact, kABPersonEmailProperty, lMap, nil);
ABRecordSetValue(contact, property, lMap, nil);
CFRelease(lMap);
}
[sectionArray removeObjectAtIndex:[indexPath row]];
NSArray *tagInsertIndexPath = [NSArray arrayWithObject:indexPath];
@ -497,6 +481,12 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
[headerController setContact:contact];
}
- (void)addPhoneField:(NSString*)number {
int i = 0;
while(i < ContactSections_MAX && contactSections[i] != ContactSections_Number) ++i;
[self addEntry:[self tableView] section:i animated:FALSE value:number];
}
- (void)addSipField:(NSString*)address {
int i = 0;
while(i < ContactSections_MAX && contactSections[i] != ContactSections_Sip) ++i;
@ -545,7 +535,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
if(contactSections[[indexPath section]] == ContactSections_Number) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index);
if(labelRef != NULL) {
label = [ContactDetailsTableViewController localizeLabel:(NSString*) labelRef];
@ -559,7 +549,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
CFRelease(lMap);
} else if(contactSections[[indexPath section]] == ContactSections_Sip) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index);
if(labelRef != NULL) {
label = [ContactDetailsTableViewController localizeLabel:(NSString*) labelRef];
@ -584,7 +574,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
CFRelease(lMap);
} else if(contactSections[[indexPath section]] == ContactSections_Email) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonEmailProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index);
if(labelRef != NULL) {
label = [ContactDetailsTableViewController localizeLabel:(NSString*) labelRef];
@ -621,7 +611,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
NSString *dest=NULL;;
if(contactSections[[indexPath section]] == ContactSections_Number) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef valueRef = ABMultiValueCopyValueAtIndex(lMap, index);
if(valueRef != NULL) {
dest = [ContactDetailsTableViewController localizeLabel:(NSString*) valueRef];
@ -630,7 +620,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
CFRelease(lMap);
} else if(contactSections[[indexPath section]] == ContactSections_Sip) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, index);
CFStringRef valueRef = CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey);
dest = [FastAddressBook normalizeSipURI:[NSString stringWithString:(NSString*) valueRef]];
@ -638,7 +628,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
CFRelease(lMap);
} else if(contactSections[[indexPath section]] == ContactSections_Email) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonEmailProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef valueRef = ABMultiValueCopyValueAtIndex(lMap, index);
if(valueRef != NULL) {
dest = [FastAddressBook normalizeSipURI:[NSString stringWithString:(NSString*) valueRef]];
@ -666,28 +656,12 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
}
} 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);
} else if(contactSections[[indexPath section]] == ContactSections_Email) {
ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonEmailProperty);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index);
ABPropertyID property = [self propertyIDForSection:contactSections[indexPath.section]];
if( property != kABInvalidPropertyType ){
ABMultiValueRef lMap = ABRecordCopyValue(contact, property);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
CFTypeRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index);
if(labelRef != NULL) {
key = [NSString stringWithString:(NSString*) labelRef];
CFRelease(labelRef);
@ -772,7 +746,7 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
int last_index = [[self getSectionData:[indexPath section]] count] - 1;
NSInteger last_index = [[self getSectionData:[indexPath section]] count] - 1;
if (indexPath.row == last_index) {
return UITableViewCellEditingStyleInsert;
}
@ -843,34 +817,21 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
- (void)changeContactDetailsLabel:(NSString *)value {
if(value != nil) {
NSMutableArray *sectionDict = [self getSectionData:[editingIndexPath section]];
Entry *entry = [sectionDict objectAtIndex:[editingIndexPath row]];
ContactSections_e thesection = contactSections[[editingIndexPath section]];
if(thesection == ContactSections_Number) {
NSInteger section = editingIndexPath.section;
NSMutableArray *sectionDict = [self getSectionData:section];
ABPropertyID property = [self propertyIDForSection:(int)section];
Entry *entry = [sectionDict objectAtIndex:editingIndexPath.row];
if( property != kABInvalidPropertyType ){
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonPhoneProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceLabelAtIndex(lMap, (CFStringRef)(value), index);
ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, nil);
CFRelease(lMap);
} else if(thesection == 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);
} else if(thesection == ContactSections_Email) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonEmailProperty);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceLabelAtIndex(lMap, (CFStringRef)(value), index);
ABRecordSetValue(contact, kABPersonEmailProperty, lMap, nil);
CFRelease(lMap);
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject: editingIndexPath] withRowAnimation:FALSE];
[self.tableView reloadSectionIndexTitles];
@ -906,26 +867,21 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
Entry *entry = [sectionDict objectAtIndex:[path row]];
ContactSections_e sect = contactSections[[path section]];
ABPropertyID property = [self propertyIDForSection:sect];
NSString *value = [textField text];
if(sect == 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(sect == ContactSections_Sip) {
if(sect == ContactSections_Sip) {
[self setSipContactEntry:entry withValue:value];
} else if(sect == ContactSections_Email) {
ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonEmailProperty);
} else if( property != kABInvalidPropertyType ){
ABMultiValueRef lcMap = ABRecordCopyValue(contact, property);
ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap);
CFRelease(lcMap);
int index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]);
ABMultiValueReplaceValueAtIndex(lMap, (CFStringRef)value, index);
ABRecordSetValue(contact, kABPersonEmailProperty, lMap, nil);
ABRecordSetValue(contact, property, lMap, nil);
CFRelease(lMap);
}
[cell.detailTextLabel setText:value];
} else {
[LinphoneLogger logc:LinphoneLoggerError format:"Not valid UIEditableTableViewCell"];

View file

@ -110,6 +110,7 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
} else {
[LinphoneLogger logc:LinphoneLoggerLog format:"Save AddressBook: Success!"];
}
[[LinphoneManager instance].fastAddressBook reload];
}
}
@ -143,82 +144,60 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
[[LinphoneManager instance].fastAddressBook reload];
}
- (void) selectContact:(ABRecordRef)acontact andReload:(BOOL)reload {
contact = NULL;
[self resetData];
contact = acontact;
[tableController setContact:contact];
if (reload) {
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
}
}
- (void) addCurrentContactContactField:(NSString*)address {
LinphoneAddress *linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
NSString *username = [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)];
if (([username rangeOfString:@"@"].length > 0) &&
([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true)) {
[tableController addEmailField:username];
} else if ((linphone_proxy_config_is_phone_number(NULL, [username UTF8String])) &&
([[LinphoneManager instance] lpConfigBoolForKey:@"save_new_contacts_as_phone_number"] == true)) {
[tableController addPhoneField:username];
} else {
[tableController addSipField:address];
}
linphone_address_destroy(linphoneAddress);
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
}
- (void)newContact {
[LinphoneLogger logc:LinphoneLoggerLog format:"New contact"];
contact = NULL;
[self resetData];
contact = ABPersonCreate();
[tableController setContact:contact];
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
[self selectContact:ABPersonCreate() andReload:YES];
}
- (void)newContact:(NSString*)address {
[LinphoneLogger logc:LinphoneLoggerLog format:"New contact"];
contact = NULL;
[self resetData];
contact = ABPersonCreate();
[tableController setContact:contact];
if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) {
LinphoneAddress *linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
NSString *username = [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)];
if ([username rangeOfString:@"@"].length > 0) {
[tableController addEmailField:username];
} else {
[tableController addSipField:address];
}
linphone_address_destroy(linphoneAddress);
} else {
[tableController addSipField:address];
}
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
[self selectContact:ABPersonCreate() andReload:NO];
[self addCurrentContactContactField:address];
}
- (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];
[self selectContact:ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact)) andReload:YES];
}
- (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];
if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) {
LinphoneAddress *linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
NSString *username = [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)];
if ([username rangeOfString:@"@"].length > 0) {
[tableController addEmailField:username];
} else {
[tableController addSipField:address];
}
linphone_address_destroy(linphoneAddress);
} else {
[tableController addSipField:address];
}
[self enableEdit:FALSE];
[[tableController tableView] reloadData];
[self selectContact:ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact)) andReload:NO];
[self addCurrentContactContactField:address];
}
#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];
[self selectContact:ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact)) andReload:NO];
}
#pragma mark - ViewController Functions
- (void)viewDidLoad{
@ -238,13 +217,6 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
[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 ||
@ -253,25 +225,7 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
} 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

View file

@ -87,18 +87,22 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf
LinphoneAddress* address = linphone_address_new([(NSString*)CFDictionaryGetValue(lDict,kABPersonInstantMessageUsernameKey) UTF8String]);
if (address) {
NSString* domain = [NSString stringWithCString:linphone_address_get_domain(address)
encoding:[NSString defaultCStringEncoding]];
const char* dom =linphone_address_get_domain(address);
if( dom != NULL ){
NSString* domain = [NSString stringWithCString:dom
encoding:[NSString defaultCStringEncoding]];
if (([filter compare:@"*" options:NSCaseInsensitiveSearch] == NSOrderedSame)
|| ([filter compare:domain options:NSCaseInsensitiveSearch] == NSOrderedSame)) {
match = true;
if (([filter compare:@"*" options:NSCaseInsensitiveSearch] == NSOrderedSame)
|| ([filter compare:domain options:NSCaseInsensitiveSearch] == NSOrderedSame)) {
match = true;
}
}
linphone_address_destroy(address);
}
}
CFRelease(lDict);
}
CFRelease(personSipAddresses);
return match;
}
@ -119,7 +123,7 @@ static int ms_strcmpfuz(const char * fuzzy_word, const char * sentence) {
}
// If the whole fuzzy was found, returns 0. Otherwise returns number of characters left.
return (within_sentence != NULL ? 0 : fuzzy_word + strlen(fuzzy_word) - c);
return (int)(within_sentence != NULL ? 0 : fuzzy_word + strlen(fuzzy_word) - c);
}
- (void)loadData {
@ -172,8 +176,12 @@ static int ms_strcmpfuz(const char * fuzzy_word, const char * sentence) {
if ([ContactSelection getNameOrEmailFilter] == nil ||
(ms_strcmpfuz([[[ContactSelection getNameOrEmailFilter] lowercaseString] UTF8String], [[name lowercaseString] UTF8String]) == 0)) {
//Get first char. However translate them to ASCII first, because foreign languages (spanish) use tildes for instance
NSString *firstCharUTF8 = [[name substringToIndex:1] uppercaseString];
NSData *data = [firstCharUTF8 dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
NSString *firstChar = [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
// Put in correct subDic
NSString *firstChar = [[name substringToIndex:1] uppercaseString];
if([firstChar characterAtIndex:0] < 'A' || [firstChar characterAtIndex:0] > 'Z') {
firstChar = @"#";
}

View file

@ -75,7 +75,7 @@ typedef enum _ContactSelectionMode {
@end
@interface ContactsViewController : UIViewController<UICompositeViewDelegate,ABPeoplePickerNavigationControllerDelegate> {
@interface ContactsViewController : UIViewController<UICompositeViewDelegate,ABPeoplePickerNavigationControllerDelegate,UISearchBarDelegate> {
BOOL use_systemView;
}
@ -94,5 +94,4 @@ typedef enum _ContactSelectionMode {
- (IBAction)onAddContactClick:(id)event;
- (IBAction)onBackClick:(id)event;
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText;
@end

View file

@ -151,6 +151,12 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// cannot change search bar icon nor text font from the interface builder...
// [_searchBar setImage:[UIImage imageNamed:@"contact_search.png" ] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
// UITextField *searchText = [_searchBar valueForKey:@"_searchField"];
// [searchText setFont:[UIFont fontWithName:@"CustomFont" size:12]];
_searchBar.showsCancelButton = (_searchBar.text.length > 0);
BOOL use_system = [[LinphoneManager instance] lpConfigBoolForKey:@"use_system_contacts"];
if( use_system && !self.sysViewController){// use system contacts
ABPeoplePickerNavigationController* picker = [[ABPeoplePickerNavigationController alloc] init];
@ -305,6 +311,11 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self searchBar:searchBar textDidChange:nil];
[searchBar resignFirstResponder];
}
#pragma mark - ABPeoplePickerDelegate
-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
@ -337,11 +348,28 @@ static UICompositeViewDescription *compositeDescription = nil;
return false;
}
#pragma mark - searchBar delegate
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
// display searchtext in UPPERCASE
// searchBar.text = [searchText uppercaseString];
searchBar.showsCancelButton = (searchText.length > 0);
[ContactSelection setNameOrEmailFilter:searchText];
[tableController loadData];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:FALSE animated:TRUE];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:TRUE animated:TRUE];
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
}
- (void)viewDidUnload {
[self setToolBar:nil];
[super viewDidUnload];

View file

@ -144,41 +144,39 @@ static UICompositeViewDescription *compositeDescription = nil;
[callButton setEnabled:TRUE];
// Update on show
if([LinphoneManager isLcReady]) {
LinphoneManager *mgr=[LinphoneManager instance];
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* call = linphone_core_get_current_call(lc);
LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0;
[self callUpdate:call state:state];
LinphoneManager *mgr=[LinphoneManager instance];
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* call = linphone_core_get_current_call(lc);
LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0;
[self callUpdate:call state:state];
if([LinphoneManager runningOnIpad]) {
if(linphone_core_video_enabled(lc) && [mgr lpConfigBoolForKey:@"preview_preference"]) {
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);
linphone_core_enable_video_preview(lc, FALSE);
[backgroundView setHidden:TRUE];
[videoCameraSwitch setHidden:TRUE];
}
if([LinphoneManager runningOnIpad]) {
if(linphone_core_video_enabled(lc) && [mgr lpConfigBoolForKey:@"preview_preference"]) {
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);
linphone_core_enable_video_preview(lc, FALSE);
[backgroundView setHidden:TRUE];
[videoCameraSwitch setHidden:TRUE];
}
}
[addressField setText:@""];
[addressField setText:@""];
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_0 // attributed string only available since iOS6
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
// fix placeholder bar color in iOS7
UIColor *color = [UIColor grayColor];
NSAttributedString* placeHolderString = [[NSAttributedString alloc]
initWithString:NSLocalizedString(@"Enter an address", @"Enter an address")
attributes:@{NSForegroundColorAttributeName: color}];
addressField.attributedPlaceholder = placeHolderString;
[placeHolderString release];
}
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
// fix placeholder bar color in iOS7
UIColor *color = [UIColor grayColor];
NSAttributedString* placeHolderString = [[NSAttributedString alloc]
initWithString:NSLocalizedString(@"Enter an address", @"Enter an address")
attributes:@{NSForegroundColorAttributeName: color}];
addressField.attributedPlaceholder = placeHolderString;
[placeHolderString release];
}
#endif
}
}
- (void)viewWillDisappear:(BOOL)animated {
@ -256,7 +254,7 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)coreUpdateEvent:(NSNotification*)notif {
if([LinphoneManager isLcReady] && [LinphoneManager runningOnIpad]) {
if([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);
@ -273,26 +271,24 @@ static UICompositeViewDescription *compositeDescription = nil;
#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 {
LinphoneCore *lc = [LinphoneManager getLc];
if(linphone_core_get_calls_nb(lc) > 0) {
if(transferMode) {
[addCallButton setHidden:true];
[callButton setHidden:false];
[backButton setHidden:true];
[addContactButton setHidden:false];
[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];
}
}

View file

@ -113,6 +113,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[HistoryDetailsViewController adaptSize:durationHeaderLabel field:durationLabel];
[HistoryDetailsViewController adaptSize:typeHeaderLabel field:typeLabel];
[HistoryDetailsViewController adaptSize:plainAddressHeaderLabel field:plainAddressLabel];
[addContactButton.titleLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack!
[callButton.titleLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack!
[messageButton.titleLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack!
}
@ -183,9 +184,6 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)update {
if(![LinphoneManager isLcReady]) {
return;
}
// Look for the call log
callLog = NULL;
@ -386,18 +384,6 @@ static UICompositeViewDescription *compositeDescription = nil;
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);

View file

@ -111,19 +111,17 @@
- (void)loadData {
[callLogs removeAllObjects];
if([LinphoneManager isLcReady]) {
const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]);
while(logs != NULL) {
LinphoneCallLog* log = (LinphoneCallLog *) logs->data;
if(missedFilter) {
if (linphone_call_log_get_status(log) == LinphoneCallMissed) {
[callLogs addObject:[NSValue valueWithPointer: log]];
}
} else {
const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]);
while(logs != NULL) {
LinphoneCallLog* log = (LinphoneCallLog *) logs->data;
if(missedFilter) {
if (linphone_call_log_get_status(log) == LinphoneCallMissed) {
[callLogs addObject:[NSValue valueWithPointer: log]];
}
logs = ms_list_next(logs);
} else {
[callLogs addObject:[NSValue valueWithPointer: log]];
}
logs = ms_list_next(logs);
}
[[self tableView] reloadData];
}

View file

@ -78,18 +78,14 @@ static UICompositeViewDescription *compositeDescription = nil;
- (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];
[self changeView: History_All];
// Reset missed call
linphone_core_reset_missed_calls_count([LinphoneManager getLc]);
// Fake event
@ -98,23 +94,8 @@ static UICompositeViewDescription *compositeDescription = nil;
- (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];
}
editButton.hidden = ([[tableView dataSource] tableView:tableView numberOfRowsInSection:0] == 0);
}
- (void)viewDidLoad {
@ -160,6 +141,8 @@ static UICompositeViewDescription *compositeDescription = nil;
} else {
missedButton.selected = FALSE;
}
editButton.hidden = ([[tableView dataSource] tableView:tableView numberOfRowsInSection:0] == 0);
}
@ -181,6 +164,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onDeleteClick:(id) event {
linphone_core_clear_call_logs([LinphoneManager getLc]);
[tableController loadData];
editButton.hidden = ([[tableView dataSource] tableView:tableView numberOfRowsInSection:0] == 0);
if([editButton isSelected]) {
[editButton toggle];
[self onEditClick:nil];

View file

@ -87,37 +87,20 @@ static UICompositeViewDescription *compositeDescription = nil;
[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];
}
}

View file

@ -35,7 +35,7 @@
@private
NSInteger totalBytesExpectedToRead;
id<ImageSharingDelegate> delegate;
int statusCode;
NSInteger statusCode;
}
+ (id)newImageSharingUpload:(NSURL*)url image:(UIImage*)image delegate:(id<ImageSharingDelegate>)delegate userInfo:(id)userInfo;

View file

@ -115,7 +115,7 @@
now lets create the body of the post
*/
NSMutableData *body = [NSMutableData data];
NSString *imageName = [NSString stringWithFormat:@"%i-%f.jpg", [image hash],[NSDate timeIntervalSinceReferenceDate]];
NSString *imageName = [NSString stringWithFormat:@"%lu-%f.jpg", (unsigned long)[image hash],[NSDate timeIntervalSinceReferenceDate]];
[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]];

107
Classes/LaunchScreen.xib Normal file
View file

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="background-launch.png" translatesAutoresizingMaskIntoConstraints="NO" id="sxt-rJ-Xjr">
<rect key="frame" x="0.0" y="53" width="480" height="374"/>
</imageView>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleAspectFit" image="logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="pz0-nR-x0f" userLabel="logo">
<rect key="frame" x="10" y="70" width="460" height="340"/>
<constraints>
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="500" id="jhC-bn-LAU"/>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="500" id="zP0-FQ-B8L"/>
</constraints>
</imageView>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="strech-top.png" translatesAutoresizingMaskIntoConstraints="NO" id="Mkx-Sj-OCT">
<rect key="frame" x="0.0" y="0.0" width="480" height="54"/>
</imageView>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="strech-bottom.png" translatesAutoresizingMaskIntoConstraints="NO" id="hjO-N8-axw">
<rect key="frame" x="0.0" y="426" width="480" height="54"/>
</imageView>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="corner-left-bottom.png" translatesAutoresizingMaskIntoConstraints="NO" id="fMp-hm-0u4">
<rect key="frame" x="0.0" y="426" width="187" height="54"/>
<constraints>
<constraint firstAttribute="height" constant="54" id="j0e-1d-CxT"/>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="187" id="pSC-Ql-eUO"/>
</constraints>
</imageView>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="corner-left-top.png" translatesAutoresizingMaskIntoConstraints="NO" id="Nah-ag-b2G">
<rect key="frame" x="0.0" y="0.0" width="187" height="54"/>
<constraints>
<constraint firstAttribute="height" constant="54" id="DfB-0A-Y2w"/>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="187" id="In0-Wf-9ye"/>
</constraints>
</imageView>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="corner-right-bottom.png" translatesAutoresizingMaskIntoConstraints="NO" id="mmR-OO-GHS">
<rect key="frame" x="293" y="426" width="187" height="54"/>
<constraints>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="187" id="3Ub-mh-okF"/>
<constraint firstAttribute="height" constant="54" id="Cvy-bX-Kmw"/>
</constraints>
</imageView>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="corner-right-top.png" translatesAutoresizingMaskIntoConstraints="NO" id="U5z-uv-4XA">
<rect key="frame" x="293" y="0.0" width="187" height="54"/>
<constraints>
<constraint firstAttribute="height" constant="54" id="JvO-A4-MZ3"/>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="187" id="Vsa-Cw-3na"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="Nah-ag-b2G" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="0Ua-U9-3jR"/>
<constraint firstAttribute="trailing" secondItem="Mkx-Sj-OCT" secondAttribute="trailing" id="0bE-cG-4eb"/>
<constraint firstAttribute="centerY" secondItem="pz0-nR-x0f" secondAttribute="centerY" id="5Fc-zB-W6p"/>
<constraint firstItem="hjO-N8-axw" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="5wh-4L-kum"/>
<constraint firstAttribute="trailing" secondItem="hjO-N8-axw" secondAttribute="trailing" id="6xB-GZ-ab2"/>
<constraint firstAttribute="centerY" secondItem="sxt-rJ-Xjr" secondAttribute="centerY" id="Fci-Yk-YE8"/>
<constraint firstAttribute="centerX" secondItem="sxt-rJ-Xjr" secondAttribute="centerX" id="HZV-eE-fyd"/>
<constraint firstItem="fMp-hm-0u4" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="JHk-2I-TEf"/>
<constraint firstAttribute="trailing" secondItem="sxt-rJ-Xjr" secondAttribute="trailing" id="N4R-bA-EGz"/>
<constraint firstItem="pz0-nR-x0f" firstAttribute="top" relation="greaterThanOrEqual" secondItem="iN0-l3-epB" secondAttribute="top" constant="70" id="O8w-6s-Ilj"/>
<constraint firstItem="pz0-nR-x0f" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="OAc-b0-w4Y"/>
<constraint firstItem="sxt-rJ-Xjr" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="SSn-fs-hBd"/>
<constraint firstAttribute="bottom" secondItem="mmR-OO-GHS" secondAttribute="bottom" id="UuR-5E-cSP"/>
<constraint firstItem="Mkx-Sj-OCT" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="YM1-yZ-AWI"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="pz0-nR-x0f" secondAttribute="bottom" constant="70" id="csL-0B-XBe"/>
<constraint firstItem="Mkx-Sj-OCT" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="frD-O4-NkM"/>
<constraint firstAttribute="bottom" secondItem="hjO-N8-axw" secondAttribute="bottom" id="jy1-Ed-AK2"/>
<constraint firstAttribute="centerX" secondItem="hjO-N8-axw" secondAttribute="centerX" id="mF7-u0-az0"/>
<constraint firstAttribute="centerX" secondItem="Mkx-Sj-OCT" secondAttribute="centerX" id="mFQ-Ep-iyz"/>
<constraint firstAttribute="trailing" secondItem="U5z-uv-4XA" secondAttribute="trailing" id="nf2-Bd-6fl"/>
<constraint firstItem="sxt-rJ-Xjr" firstAttribute="top" secondItem="Nah-ag-b2G" secondAttribute="bottom" constant="-1" id="pml-hI-aZZ"/>
<constraint firstItem="Mkx-Sj-OCT" firstAttribute="height" secondItem="U5z-uv-4XA" secondAttribute="height" id="qke-PJ-6Iy"/>
<constraint firstAttribute="centerX" secondItem="pz0-nR-x0f" secondAttribute="centerX" id="sIh-Bg-0MZ"/>
<constraint firstItem="fMp-hm-0u4" firstAttribute="top" secondItem="sxt-rJ-Xjr" secondAttribute="bottom" constant="-1" id="tso-TD-8RN"/>
<constraint firstItem="U5z-uv-4XA" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="txE-Z5-fPI"/>
<constraint firstItem="Nah-ag-b2G" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="vdc-ri-iKX"/>
<constraint firstAttribute="bottom" secondItem="fMp-hm-0u4" secondAttribute="bottom" id="wW6-W6-PtF"/>
<constraint firstAttribute="trailing" secondItem="mmR-OO-GHS" secondAttribute="trailing" id="zHx-QB-MaY"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="pz0-nR-x0f" secondAttribute="trailing" constant="10" id="zvX-0I-um7"/>
<constraint firstItem="mmR-OO-GHS" firstAttribute="height" secondItem="hjO-N8-axw" secondAttribute="height" id="zyn-hq-BJe"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="561.5" y="471.5"/>
</view>
</objects>
<resources>
<image name="background-launch.png" width="1536" height="1580"/>
<image name="corner-left-bottom.png" width="748" height="215"/>
<image name="corner-left-top.png" width="748" height="215"/>
<image name="corner-right-bottom.png" width="748" height="215"/>
<image name="corner-right-top.png" width="748" height="215"/>
<image name="logo.png" width="958" height="801"/>
<image name="strech-bottom.png" width="40" height="215"/>
<image name="strech-top.png" width="40" height="215"/>
</resources>
</document>

View file

@ -1,243 +0,0 @@
<?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

@ -26,13 +26,11 @@
@interface LinphoneAppDelegate : NSObject <UIApplicationDelegate,UIAlertViewDelegate> {
@private
UIBackgroundTaskIdentifier bgStartId;
BOOL started;
int savedMaxCall;
BOOL startedInBackground;
}
- (void)processRemoteNotification:(NSDictionary*)userInfo;
@property (assign) BOOL started;
@property (nonatomic, retain) UIAlertView *waitingIndicator;
@property (nonatomic, retain) NSString *configURL;
@property (nonatomic, strong) UIWindow* window;

View file

@ -24,7 +24,6 @@
#import "CoreTelephony/CTCallCenter.h"
#import "CoreTelephony/CTCall.h"
#import "ConsoleViewController.h"
#import "LinphoneCoreSettingsStore.h"
#include "LinphoneManager.h"
@ -32,7 +31,7 @@
@implementation LinphoneAppDelegate
@synthesize started,configURL;
@synthesize configURL;
@synthesize window;
#pragma mark - Lifecycle Functions
@ -40,7 +39,7 @@
- (id)init {
self = [super init];
if(self != nil) {
self->started = FALSE;
self->startedInBackground = FALSE;
}
return self;
}
@ -55,18 +54,15 @@
- (void)applicationDidEnterBackground:(UIApplication *)application{
[LinphoneLogger logc:LinphoneLoggerLog format:"applicationDidEnterBackground"];
if(![LinphoneManager isLcReady]) return;
Linphone_log(@"%@", NSStringFromSelector(_cmd));
[[LinphoneManager instance] enterBackgroundMode];
}
- (void)applicationWillResignActive:(UIApplication *)application {
[LinphoneLogger logc:LinphoneLoggerLog format:"applicationWillResignActive"];
if(![LinphoneManager isLcReady]) return;
Linphone_log(@"%@", NSStringFromSelector(_cmd));
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* call = linphone_core_get_current_call(lc);
if (call){
/* save call context */
LinphoneManager* instance = [LinphoneManager instance];
@ -86,9 +82,13 @@
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[LinphoneLogger logc:LinphoneLoggerLog format:"applicationDidBecomeActive"];
[self startApplication];
Linphone_log(@"%@", NSStringFromSelector(_cmd));
if( startedInBackground ){
startedInBackground = FALSE;
[[PhoneMainView instance] startUp];
[[PhoneMainView instance] updateStatusBar:nil];
}
LinphoneManager* instance = [LinphoneManager instance];
[instance becomeActive];
@ -114,70 +114,70 @@
}
}
- (UIUserNotificationCategory*)newMessageNotificationCategory {
- (UIUserNotificationCategory*)getMessageNotificationCategory {
UIMutableUserNotificationAction* reply = [[UIMutableUserNotificationAction alloc] init];
UIMutableUserNotificationAction* reply = [[[UIMutableUserNotificationAction alloc] init] autorelease];
reply.identifier = @"reply";
reply.title = NSLocalizedString(@"Reply", nil);
reply.activationMode = UIUserNotificationActivationModeForeground;
reply.destructive = NO;
reply.authenticationRequired = YES;
UIMutableUserNotificationAction* mark_read = [[UIMutableUserNotificationAction alloc] init];
UIMutableUserNotificationAction* mark_read = [[[UIMutableUserNotificationAction alloc] init] autorelease];
mark_read.identifier = @"mark_read";
mark_read.title = NSLocalizedString(@"Mark Read", nil);
mark_read.activationMode = UIUserNotificationActivationModeBackground;
mark_read.destructive = NO;
mark_read.authenticationRequired = NO;
NSArray* localRingActions = @[mark_read, reply];
UIMutableUserNotificationCategory* localRingNotifAction = [[UIMutableUserNotificationCategory alloc] init];
UIMutableUserNotificationCategory* localRingNotifAction = [[[UIMutableUserNotificationCategory alloc] init] autorelease];
localRingNotifAction.identifier = @"incoming_msg";
[localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault];
[localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextMinimal];
return localRingNotifAction;
}
- (UIUserNotificationCategory*)newCallNotificationCategory {
UIMutableUserNotificationAction* Answer = [[UIMutableUserNotificationAction alloc] init];
Answer.identifier = @"answer";
Answer.title = NSLocalizedString(@"Answer", nil);
Answer.activationMode = UIUserNotificationActivationModeForeground;
Answer.destructive = NO;
Answer.authenticationRequired = YES;
- (UIUserNotificationCategory*)getCallNotificationCategory {
UIMutableUserNotificationAction* answer = [[[UIMutableUserNotificationAction alloc] init] autorelease];
answer.identifier = @"answer";
answer.title = NSLocalizedString(@"Answer", nil);
answer.activationMode = UIUserNotificationActivationModeForeground;
answer.destructive = NO;
answer.authenticationRequired = YES;
UIMutableUserNotificationAction* Decline = [[UIMutableUserNotificationAction alloc] init];
Decline.identifier = @"decline";
Decline.title = NSLocalizedString(@"Decline", nil);
Decline.activationMode = UIUserNotificationActivationModeBackground;
Decline.destructive = YES;
Decline.authenticationRequired = NO;
UIMutableUserNotificationAction* decline = [[[UIMutableUserNotificationAction alloc] init] autorelease];
decline.identifier = @"decline";
decline.title = NSLocalizedString(@"Decline", nil);
decline.activationMode = UIUserNotificationActivationModeBackground;
decline.destructive = YES;
decline.authenticationRequired = NO;
NSArray* localRingActions = @[Decline, Answer];
NSArray* localRingActions = @[decline, answer];
UIMutableUserNotificationCategory* localRingNotifAction = [[UIMutableUserNotificationCategory alloc] init];
UIMutableUserNotificationCategory* localRingNotifAction = [[[UIMutableUserNotificationCategory alloc] init] autorelease];
localRingNotifAction.identifier = @"incoming_call";
[localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault];
[localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextMinimal];
return localRingNotifAction;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIApplication* app= [UIApplication sharedApplication];
UIApplicationState state = app.applicationState;
if( [app respondsToSelector:@selector(registerUserNotificationSettings:)] ){
/* iOS8 notifications can be actioned! Awesome: */
UIUserNotificationType notifTypes = UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert;
NSSet* categories = [NSSet setWithObjects:[self newCallNotificationCategory], [self newMessageNotificationCategory], nil];
NSSet* categories = [NSSet setWithObjects:[self getCallNotificationCategory], [self getMessageNotificationCategory], nil];
UIUserNotificationSettings* userSettings = [UIUserNotificationSettings settingsForTypes:notifTypes categories:categories];
[app registerUserNotificationSettings:userSettings];
[app registerForRemoteNotifications];
@ -185,14 +185,13 @@
NSUInteger notifTypes = UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeNewsstandContentAvailability;
[app registerForRemoteNotificationTypes:notifTypes];
}
LinphoneManager* instance = [LinphoneManager instance];
BOOL background_mode = [instance lpConfigBoolForKey:@"backgroundmode_preference"];
BOOL start_at_boot = [instance lpConfigBoolForKey:@"start_at_boot_preference"];
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
if (state == UIApplicationStateBackground)
{
// we've been woken up directly to background;
if( !start_at_boot || !background_mode ) {
@ -207,44 +206,35 @@
[LinphoneLogger log:LinphoneLoggerWarning format:@"Background task for application launching expired."];
[[UIApplication sharedApplication] endBackgroundTask:bgStartId];
}];
[self startApplication];
[[LinphoneManager instance] startLibLinphone];
// initialize UI
[self.window makeKeyAndVisible];
[RootViewManager setupWithPortrait:(PhoneMainView*)self.window.rootViewController];
[[PhoneMainView instance] startUp];
[[PhoneMainView instance] updateStatusBar:nil];
NSDictionary *remoteNotif =[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotif){
[LinphoneLogger log:LinphoneLoggerLog format:@"PushNotification from launch received."];
[self processRemoteNotification:remoteNotif];
}
if (bgStartId!=UIBackgroundTaskInvalid) [[UIApplication sharedApplication] endBackgroundTask:bgStartId];
[[PhoneMainView instance] updateStatusBar:nil];
return YES;
}
- (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;
[self.window makeKeyAndVisible];
[RootViewManager setupWithPortrait:(PhoneMainView*)self.window.rootViewController];
[[PhoneMainView instance] startUp];
}
}
}
- (void)applicationWillTerminate:(UIApplication *)application {
[LinphoneLogger log:LinphoneLoggerLog format:@"Application Will Terminate"];
Linphone_log(@"%@", NSStringFromSelector(_cmd));
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSString *scheme = [[url scheme] lowercaseString];
if ([scheme isEqualToString:@"linphone-config-http"] || [scheme isEqualToString:@"linphone-config-https"]) {
configURL = [[NSString alloc] initWithString:[[url absoluteString] stringByReplacingOccurrencesOfString:@"linphone-config-" withString:@""]];
if ([scheme isEqualToString:@"linphone-config"] || [scheme isEqualToString:@"linphone-config"]) {
NSString* encodedURL = [[url absoluteString] stringByReplacingOccurrencesOfString:@"linphone-config://" withString:@""];
self.configURL = [encodedURL stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
UIAlertView* confirmation = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Remote configuration",nil)
message:NSLocalizedString(@"This operation will load a remote configuration. Continue ?",nil)
delegate:self
@ -254,14 +244,11 @@
[confirmation show];
[confirmation release];
} else {
[self startApplication];
if([LinphoneManager isLcReady]) {
if([[url scheme] isEqualToString:@"sip"]) {
// Go to Dialer view
DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
if(controller != nil) {
[controller setAddress:[url absoluteString]];
}
if([[url scheme] isEqualToString:@"sip"]) {
// Go to Dialer view
DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController);
if(controller != nil) {
[controller setAddress:[url absoluteString]];
}
}
}
@ -317,8 +304,8 @@
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[LinphoneLogger log:LinphoneLoggerLog format:@"PushNotification: Receive %@", userInfo];
Linphone_log(@"%@ : %@", NSStringFromSelector(_cmd), userInfo);
[self processRemoteNotification:userInfo];
}
@ -337,12 +324,13 @@
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
Linphone_log(@"%@ - state = %ld", NSStringFromSelector(_cmd), (long)application.applicationState);
[self fixRing];
if([notification.userInfo objectForKey:@"callId"] != nil) {
BOOL auto_answer = TRUE;
// some local notifications have an internal timer to relaunch themselves at specified intervals
if( [[notification.userInfo objectForKey:@"timer"] intValue] == 1 ){
[[LinphoneManager instance] cancelLocalNotifTimerForCallId:[notification.userInfo objectForKey:@"callId"]];
@ -375,6 +363,7 @@
// this method is implemented for iOS7. It is invoked when receiving a push notification for a call and it has "content-available" in the aps section.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
Linphone_log(@"%@ : %@", NSStringFromSelector(_cmd), userInfo);
LinphoneManager* lm = [LinphoneManager instance];
if (lm.pushNotificationToken==Nil){
@ -382,12 +371,6 @@
return;
}
// check that linphone is still running
if( ![LinphoneManager isLcReady] )
[lm startLibLinphone];
[LinphoneLogger log:LinphoneLoggerLog format:@"Silent PushNotification; userInfo %@", userInfo];
// save the completion handler for later execution.
// 2 outcomes:
// - if a new call/message is received, the completion handler will be called with "NEWDATA"
@ -409,22 +392,23 @@
#pragma mark - PushNotification Functions
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
[LinphoneLogger log:LinphoneLoggerLog format:@"PushNotification: Token %@", deviceToken];
Linphone_log(@"%@ : %@", NSStringFromSelector(_cmd), deviceToken);
[[LinphoneManager instance] setPushNotificationToken:deviceToken];
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
[LinphoneLogger log:LinphoneLoggerError format:@"PushNotification: Error %@", [error localizedDescription]];
Linphone_log(@"%@ : %@", NSStringFromSelector(_cmd), [error localizedDescription]);
[[LinphoneManager instance] setPushNotificationToken:nil];
}
#pragma mark - User notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[LinphoneLogger log:LinphoneLoggerLog format:@"%@", NSStringFromSelector(_cmd)];
Linphone_log(@"%@", NSStringFromSelector(_cmd));
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler {
Linphone_log(@"%@", NSStringFromSelector(_cmd));
if( [[UIDevice currentDevice].systemVersion floatValue] >= 8){
LinphoneCore* lc = [LinphoneManager getLc];
@ -455,6 +439,7 @@
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
Linphone_log(@"%@", NSStringFromSelector(_cmd));
completionHandler();
}
@ -516,37 +501,20 @@
{
if ((alertView.tag == 1) && (buttonIndex==1)) {
[self showWaitingIndicator];
if([LinphoneManager isLcReady]) {
[self attemptRemoteConfiguration];
} else {
[[LinphoneManager instance] startLibLinphone];
[self performSelector:@selector(attemptRemoteConfiguration) withObject:NULL afterDelay:5.0];
}
[self attemptRemoteConfiguration];
}
}
- (void)attemptRemoteConfiguration {
if ([LinphoneManager isLcReady]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(ConfigurationStateUpdateEvent:)
name:kLinphoneConfiguringStateUpdate
object:nil];
linphone_core_set_provisioning_uri([LinphoneManager getLc] , [configURL UTF8String]);
[[LinphoneManager instance] destroyLibLinphone];
[[LinphoneManager instance] startLibLinphone];
} else {
[_waitingIndicator dismissWithClickedButtonIndex:0 animated:true];
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Failure",nil)
message:NSLocalizedString(@"Linphone is not ready.",nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK",nil)
otherButtonTitles:nil];
[error show];
[error release];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(ConfigurationStateUpdateEvent:)
name:kLinphoneConfiguringStateUpdate
object:nil];
linphone_core_set_provisioning_uri([LinphoneManager getLc] , [configURL UTF8String]);
[[LinphoneManager instance] destroyLibLinphone];
[[LinphoneManager instance] startLibLinphone];
}

View file

@ -293,6 +293,10 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
[alertview release];
}
+ (BOOL)hasSipPrefix:(NSString*)str {
return [str hasPrefix:@"sip:"] || [str hasPrefix:@"sips:"];
}
- (void)synchronizeAccount {
LinphoneCore *lc = [LinphoneManager getLc];
LpConfig* conf = linphone_core_get_config(lc);
@ -352,9 +356,11 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
if( isWifiOnly && [LinphoneManager instance].connectivity == wwan ) expire = 0;
if ((!proxyAddress || [proxyAddress length] <1 ) && domain) {
proxyAddress = [NSString stringWithFormat:@"sip:%@",domain] ;
} else {
proxyAddress = [NSString stringWithFormat:@"sip:%@",proxyAddress] ;
proxyAddress = domain;
}
if( ![LinphoneCoreSettingsStore hasSipPrefix:proxyAddress] ) {
proxyAddress = [NSString stringWithFormat:@"sip:%@",proxyAddress];
}
char* proxy = ms_strdup([proxyAddress cStringUsingEncoding:[NSString defaultCStringEncoding]]);
@ -407,7 +413,7 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
}
lp_config_set_int(conf, LINPHONERC_APPLICATION_KEY, "pushnotification_preference", pushnotification);
if( pushnotification ) [[LinphoneManager instance] addPushTokenToProxyConfig:proxyCfg];
[[LinphoneManager instance] configurePushTokenForProxyConfig:proxyCfg];
linphone_proxy_config_enable_register(proxyCfg, true);
linphone_proxy_config_enable_avpf(proxyCfg, use_avpf);
@ -478,14 +484,14 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
bool range = [match rangeAtIndex:2].length > 0;
if(!range) {
NSRange rangeMinPort = [match rangeAtIndex:1];
*minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] integerValue]];
*minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] intValue]];
*maxPort = *minPort;
return TRUE;
} else {
NSRange rangeMinPort = [match rangeAtIndex:1];
*minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] integerValue]];
*minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] intValue]];
NSRange rangeMaxPort = [match rangeAtIndex:4];
*maxPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMaxPort] integerValue]];
*maxPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMaxPort] intValue]];
if(*minPort > *maxPort) {
*minPort = *maxPort;
}
@ -496,7 +502,6 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
}
- (BOOL)synchronize {
if (![LinphoneManager isLcReady]) return YES;
LinphoneCore *lc=[LinphoneManager getLc];
BOOL account_changed;
@ -684,13 +689,8 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args);
BOOL debugmode = [self boolForKey:@"debugenable_preference"];
lp_config_set_int(config, 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();
}
[[LinphoneManager instance] setLogsEnabled:debugmode];
BOOL animations = [self boolForKey:@"animations_preference"];
lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "animations_preference", animations);

View file

@ -98,15 +98,13 @@ struct NetworkReachabilityContext {
@end
typedef struct _LinphoneManagerSounds {
SystemSoundID call;
SystemSoundID message;
SystemSoundID vibrate;
} LinphoneManagerSounds;
@interface LinphoneManager : NSObject {
@protected
SCNetworkReachabilityRef proxyReachability;
@private
NSTimer* mIterateTimer;
NSMutableArray* pendindCallIdFromRemoteNotif;
@ -132,7 +130,7 @@ typedef struct _LinphoneManagerSounds {
+ (NSString *)getUserAgent;
+ (int)unreadMessageCount;
- (void)playMessageSound;
- (void)resetLinphoneCore;
- (void)startLibLinphone;
- (void)destroyLibLinphone;
@ -140,12 +138,12 @@ typedef struct _LinphoneManagerSounds {
- (void)becomeActive;
- (BOOL)enterBackgroundMode;
- (void)enableAutoAnswerForCallId:(NSString*) callid;
- (void)addPushTokenToProxyConfig: (LinphoneProxyConfig*)cfg;
- (void)configurePushTokenForProxyConfig: (LinphoneProxyConfig*)cfg;
- (BOOL)shouldAutoAcceptCallForCallId:(NSString*) callId;
- (void)acceptCallForCallId:(NSString*)callid;
- (void)cancelLocalNotifTimerForCallId:(NSString*)callid;
+ (BOOL)langageDirectionIsRTL;
+ (void)kickOffNetworkConnection;
- (void)setupNetworkReachabilityCallback;
@ -154,6 +152,7 @@ typedef struct _LinphoneManagerSounds {
- (bool)allowSpeaker;
- (void)configureVbrCodecs;
- (void)setLogsEnabled:(BOOL)enabled;
+ (BOOL)copyFile:(NSString*)src destination:(NSString*)dst override:(BOOL)override;
+ (NSString*)bundleFile:(NSString*)file;
@ -186,6 +185,7 @@ typedef struct _LinphoneManagerSounds {
@property (readonly) NetworkType network;
@property (readonly) const char* frontCamId;
@property (readonly) const char* backCamId;
@property (retain, nonatomic) NSString* SSID;
@property (readonly) sqlite3* database;
@property (nonatomic, retain) NSData *pushNotificationToken;
@property (readonly) LinphoneManagerSounds sounds;

View file

@ -27,6 +27,7 @@
#import <AudioToolbox/AudioToolbox.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <CoreTelephony/CTCallCenter.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import "LinphoneManager.h"
#import "LinphoneCoreSettingsStore.h"
@ -35,6 +36,10 @@
#include "linphone/lpconfig.h"
#include "mediastreamer2/mscommon.h"
#import "LinphoneIOSVersion.h"
#import <AVFoundation/AVAudioPlayer.h>
#define LINPHONE_LOGS_MAX_ENTRY 5000
static void audioRouteChangeListenerCallback (
@ -96,6 +101,12 @@ NSString *const kLinphoneInternalChatDBFilename = @"linphone_chats.db";
[super dealloc];
}
@end
@interface LinphoneManager ()
@property (retain, nonatomic) AVAudioPlayer* messagePlayer;
@end
@implementation LinphoneManager
@synthesize connectivity;
@ -137,8 +148,11 @@ struct codec_name_pref_table codec_pref_table[]={
{ "mp4v-es", 90000, @"mp4v-es_preference"},
{ "h264", 90000, @"h264_preference"},
{ "vp8", 90000, @"vp8_preference"},
{ "mpeg4-generic", 44100, @"aaceld_44k_preference"},
{ "mpeg4-generic", 22050, @"aaceld_22k_preference"},
{ "mpeg4-generic", 16000, @"aaceld_16k_preference"},
{ "mpeg4-generic", 22050, @"aaceld_22k_preference"},
{ "mpeg4-generic", 32000, @"aaceld_32k_preference"},
{ "mpeg4-generic", 44100, @"aaceld_44k_preference"},
{ "mpeg4-generic", 48000, @"aaceld_48k_preference"},
{ "opus", 48000, @"opus_preference"},
{ NULL,0,Nil }
};
@ -159,7 +173,6 @@ struct codec_name_pref_table codec_pref_table[]={
codec_pref_table[i].name,
codec_pref_table[i].rate,
LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS);
if( (available == NULL)
// these two codecs should not be hidden, even if not supported
&& ![codec_pref_table[i].prefname isEqualToString:@"h264_preference"]
@ -232,6 +245,15 @@ struct codec_name_pref_table codec_pref_table[]={
}
#endif
+ (BOOL)langageDirectionIsRTL {
static NSLocaleLanguageDirection dir = NSLocaleLanguageDirectionLeftToRight;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dir = [NSLocale characterDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]];
});
return dir == NSLocaleLanguageDirectionRightToLeft;
}
#pragma mark - Lifecycle Functions
- (id)init {
@ -242,26 +264,13 @@ struct codec_name_pref_table codec_pref_table[]={
[LinphoneLogger logc:LinphoneLoggerError format:"cannot register route change handler [%ld]",lStatus];
}
// Sounds
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"ring" ofType:@"wav"];
sounds.call = 0;
OSStatus status = AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &sounds.call);
if(status != 0){
[LinphoneLogger log:LinphoneLoggerWarning format:@"Can't set \"call\" system sound"];
}
}
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"];
sounds.message = 0;
OSStatus status = AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &sounds.message);
if(status != 0){
[LinphoneLogger log:LinphoneLoggerWarning format:@"Can't set \"message\" system sound"];
}
}
sounds.vibrate = kSystemSoundID_Vibrate;
logs = [[NSMutableArray alloc] init];
NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"];
self.messagePlayer = [[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:nil] autorelease];
sounds.vibrate = kSystemSoundID_Vibrate;
logs = [[NSMutableArray alloc] init];
database = NULL;
speakerEnabled = FALSE;
bluetoothEnabled = FALSE;
@ -274,8 +283,6 @@ struct codec_name_pref_table codec_pref_table[]={
NSString *confiFileName = [LinphoneManager documentFile:@".linphonerc"];
configDb=lp_config_new_with_factory([confiFileName cStringUsingEncoding:[NSString defaultCStringEncoding]] , [factoryConfig cStringUsingEncoding:[NSString defaultCStringEncoding]]);
[self migrateFromUserPrefs];
//set default values for first boot
if (lp_config_get_string(configDb,LINPHONERC_APPLICATION_KEY,"debugenable_preference",NULL)==NULL){
#ifdef DEBUG
@ -284,18 +291,13 @@ struct codec_name_pref_table codec_pref_table[]={
[self lpConfigSetBool:FALSE forKey:@"debugenable_preference"];
#endif
}
[self migrateFromUserPrefs];
}
return self;
}
- (void)dealloc {
if(sounds.call) {
AudioServicesDisposeSystemSoundID(sounds.call);
}
if(sounds.message) {
AudioServicesDisposeSystemSoundID(sounds.message);
}
[fastAddressBook release];
[logs release];
@ -459,7 +461,7 @@ exit_dbmigration:
@"start_at_boot_preference" :@YES};
BOOL shouldSync = FALSE;
Linphone_log(@"%d user prefs", [defaults_keys count]);
Linphone_log(@"%lu user prefs", (unsigned long)[defaults_keys count]);
for( NSString* userpref in values ){
if( [defaults_keys containsObject:userpref] ){
@ -656,8 +658,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char
}
[lCTCallCenter release];
if( [[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
LinphoneCallLog* callLog=linphone_call_get_call_log(call);
NSString* callId=[NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)];
@ -667,15 +668,20 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char
// Create a new local notification
data->notification = [[UILocalNotification alloc] init];
if (data->notification) {
data->timer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(localNotifContinue:) userInfo:data->notification repeats:TRUE];
// iOS8 doesn't need the timer trick for the local notification.
if( [[UIDevice currentDevice].systemVersion floatValue] >= 8){
data->notification.soundName = @"ring.caf";
data->notification.category = @"incoming_call";
} else {
data->notification.soundName = @"shortring.caf";
data->timer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(localNotifContinue:) userInfo:data->notification repeats:TRUE];
}
data->notification.repeatInterval = 0;
if( [[UIDevice currentDevice].systemVersion floatValue] >= 8){
data->notification.category = @"incoming_call";
}
data->notification.alertBody =[NSString stringWithFormat:NSLocalizedString(@"IC_MSG",nil), address];
data->notification.alertAction = NSLocalizedString(@"Answer", nil);
data->notification.soundName = @"shortring.caf";
data->notification.userInfo = @{@"callId": callId, @"timer":[NSNumber numberWithInt:1] };
data->notification.applicationIconBadgeNumber = 1;
@ -688,7 +694,9 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char
incallBgTask=0;
}];
[[NSRunLoop currentRunLoop] addTimer:data->timer forMode:NSRunLoopCommonModes];
if( data->timer ){
[[NSRunLoop currentRunLoop] addTimer:data->timer forMode:NSRunLoopCommonModes];
}
}
}
@ -871,8 +879,7 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo
silentPushCompletion = nil;
}
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
const LinphoneAddress* remoteAddress = linphone_chat_message_get_from_address(msg);
char* c_address = linphone_address_as_string_uri_only(remoteAddress);
@ -954,19 +961,81 @@ static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChat
#pragma mark - Network Functions
- (SCNetworkReachabilityRef) getProxyReachability {
return proxyReachability;
}
+ (void)kickOffNetworkConnection {
/*start a new thread to avoid blocking the main ui in case of peer host failure*/
static BOOL in_progress = FALSE;
if( in_progress ){
Linphone_warn(@"Connection kickoff already in progress");
return;
}
in_progress = TRUE;
/* start a new thread to avoid blocking the main ui in case of peer host failure */
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
static int sleep_us = 10000;
static int timeout_s = 5;
BOOL timeout_reached = FALSE;
int loop = 0;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.0.200"/*"linphone.org"*/, 15000, nil, &writeStream);
CFWriteStreamOpen (writeStream);
BOOL res = CFWriteStreamOpen (writeStream);
const char* buff="hello";
CFWriteStreamWrite (writeStream,(const UInt8*)buff,strlen(buff));
time_t start = time(NULL);
time_t loop_time;
if( res == FALSE ){
Linphone_log(@"Could not open write stream, backing off");
CFRelease(writeStream);
in_progress = FALSE;
return;
}
// check stream status and handle timeout
CFStreamStatus status = CFWriteStreamGetStatus(writeStream);
while (status != kCFStreamStatusOpen && status != kCFStreamStatusError ) {
usleep(sleep_us);
status = CFWriteStreamGetStatus(writeStream);
loop_time = time(NULL);
if( loop_time - start >= timeout_s){
timeout_reached = TRUE;
break;
}
loop++;
}
if (status == kCFStreamStatusOpen ) {
CFWriteStreamWrite (writeStream,(const UInt8*)buff,strlen(buff));
} else if( !timeout_reached ){
CFErrorRef error = CFWriteStreamCopyError(writeStream);
Linphone_dbg(@"CFStreamError: %@", error);
CFRelease(error);
} else if( timeout_reached ){
Linphone_log(@"CFStream timeout reached");
}
CFWriteStreamClose (writeStream);
CFRelease(writeStream);
in_progress = FALSE;
});
}
+ (NSString*)getCurrentWifiSSID {
#if TARGET_IPHONE_SIMULATOR
return @"Sim_err_SSID_NotSupported";
#else
NSString *data = nil;
CFDictionaryRef dict = CNCopyCurrentNetworkInfo((CFStringRef)@"en0");
if(dict) {
[LinphoneLogger log:LinphoneLoggerDebug format:@"AP Wifi: %@", dict];
data = [NSString stringWithString:(NSString*) CFDictionaryGetValue(dict, @"SSID")];
CFRelease(dict);
}
return data;
#endif
}
static void showNetworkFlags(SCNetworkReachabilityFlags flags){
[LinphoneLogger logc:LinphoneLoggerLog format:"Network connection flags:"];
if (flags==0) [LinphoneLogger logc:LinphoneLoggerLog format:"no flags."];
@ -988,6 +1057,22 @@ static void showNetworkFlags(SCNetworkReachabilityFlags flags){
[LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsIsWWAN"];
}
static void networkReachabilityNotification(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
LinphoneManager *mgr = [LinphoneManager instance];
SCNetworkReachabilityFlags flags;
// for an unknown reason, we are receiving multiple time the notification, so
// we will skip each time the SSID did not change
NSString *newSSID = [LinphoneManager getCurrentWifiSSID];
if ([newSSID compare:mgr.SSID] == NSOrderedSame) return;
mgr.SSID = newSSID;
if (SCNetworkReachabilityGetFlags([mgr getProxyReachability], &flags)) {
networkReachabilityCallBack([mgr getProxyReachability],flags,nil);
}
}
void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* nilCtx){
showNetworkFlags(flags);
LinphoneManager* lLinphoneMgr = [LinphoneManager instance];
@ -1017,9 +1102,9 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
&& (lLinphoneMgr.connectivity == newConnectivity || lLinphoneMgr.connectivity == none)) {
linphone_proxy_config_expires(proxy, 0);
} else if (proxy){
int defaultExpire = [[LinphoneManager instance] lpConfigIntForKey:@"default_expires"];
NSInteger defaultExpire = [[LinphoneManager instance] lpConfigIntForKey:@"default_expires"];
if (defaultExpire>=0)
linphone_proxy_config_expires(proxy, defaultExpire);
linphone_proxy_config_expires(proxy, (int)defaultExpire);
//else keep default value from linphonecore
}
@ -1068,6 +1153,22 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
proxyReachability = nil;
}
// This notification is used to detect SSID change (switch of Wifi network). The ReachabilityCallback is
// not triggered when switching between 2 private Wifi...
// Since we cannot be sure we were already observer, remove ourself each time... to be improved
_SSID = [[LinphoneManager getCurrentWifiSSID] retain];
CFNotificationCenterRemoveObserver(
CFNotificationCenterGetDarwinNotifyCenter(),
self,
CFSTR("com.apple.system.config.network_change"),
NULL);
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
self,
networkReachabilityNotification,
CFSTR("com.apple.system.config.network_change"),
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
proxyReachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
if (!SCNetworkReachabilitySetCallback(proxyReachability, (SCNetworkReachabilityCallBack)networkReachabilityCallBack, ctx)){
@ -1078,6 +1179,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
[LinphoneLogger logc:LinphoneLoggerError format:"Cannot register schedule reachability cb: %s", SCErrorString(SCError())];
return;
}
// this check is to know network connectivity right now without waiting for a change. Don'nt remove it unless you have good reason. Jehan
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(proxyReachability, &flags)) {
@ -1147,8 +1249,8 @@ static LinphoneCoreVTable linphonec_vtable = {
NSString *chatDBFileName = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename];
const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
linphone_core_set_user_agent(theLinphoneCore,"LinphoneIPhone",
[[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey] UTF8String]);
linphone_core_set_user_agent(theLinphoneCore, [[[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"] stringByAppendingString:@"Iphone"] UTF8String], LINPHONE_IOS_VERSION);
[_contactSipField release];
_contactSipField = [[self lpConfigStringForKey:@"contact_im_type_value" withDefault:@"SIP"] retain];
@ -1291,8 +1393,7 @@ static BOOL libStarted = FALSE;
[error release];
}
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
&& [UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
//go directly to bg mode
[self enterBackgroundMode];
}
@ -1330,16 +1431,21 @@ static BOOL libStarted = FALSE;
#endif
/*to make sure we don't loose debug trace*/
if ([self lpConfigBoolForKey:@"debugenable_preference"]) {
if ([self lpConfigBoolForKey:@"debugenable_preference"]) {
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);
/*must be done before creating linphone core to get its traces too*/
}
linphone_core_set_log_collection_path([[LinphoneManager cacheDirectory] UTF8String]);
linphone_core_enable_log_collection([self lpConfigBoolForKey:@"debugenable_preference"]);
theLinphoneCore = linphone_core_new_with_config (&linphonec_vtable
,configDb
,self /* user_data */);
/* set the CA file no matter what, since the remote provisioning could be hitting an HTTPS server */
const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
linphone_core_set_root_ca(theLinphoneCore, lRootCa);
@ -1404,45 +1510,39 @@ static int comp_call_id(const LinphoneCall* call , const char *callid) {
}
- (void)cancelLocalNotifTimerForCallId:(NSString*)callid {
//first, make sure this callid is not already involved in a call
if ([LinphoneManager isLcReady]) {
MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore);
MSList* call = ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String]);
if (call != NULL) {
LinphoneCallAppData* data = linphone_call_get_user_pointer((LinphoneCall*)call->data);
if ( data->timer )
[data->timer invalidate];
data->timer = nil;
return;
}
}
//first, make sure this callid is not already involved in a call
MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore);
MSList* call = ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String]);
if (call != NULL) {
LinphoneCallAppData* data = linphone_call_get_user_pointer((LinphoneCall*)call->data);
if ( data->timer )
[data->timer invalidate];
data->timer = nil;
return;
}
}
- (void)acceptCallForCallId:(NSString*)callid {
//first, make sure this callid is not already involved in a call
if ([LinphoneManager isLcReady]) {
MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore);
MSList* call = ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String]);
if (call != NULL) {
[self acceptCall:(LinphoneCall*)call->data];
return;
};
}
//first, make sure this callid is not already involved in a call
MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore);
MSList* call = ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String]);
if (call != NULL) {
[self acceptCall:(LinphoneCall*)call->data];
return;
};
}
- (void)enableAutoAnswerForCallId:(NSString*) callid {
//first, make sure this callid is not already involved in a call
if ([LinphoneManager isLcReady]) {
MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore);
if (ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String])) {
[LinphoneLogger log:LinphoneLoggerWarning format:@"Call id [%@] already handled",callid];
return;
};
}
if ([pendindCallIdFromRemoteNotif count] > 10 /*max number of pending notif*/)
[pendindCallIdFromRemoteNotif removeObjectAtIndex:0];
[pendindCallIdFromRemoteNotif addObject:callid];
//first, make sure this callid is not already involved in a call
MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore);
if (ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String])) {
[LinphoneLogger log:LinphoneLoggerWarning format:@"Call id [%@] already handled",callid];
return;
};
if ([pendindCallIdFromRemoteNotif count] > 10 /*max number of pending notif*/)
[pendindCallIdFromRemoteNotif removeObjectAtIndex:0];
[pendindCallIdFromRemoteNotif addObject:callid];
}
- (BOOL)shouldAutoAcceptCallForCallId:(NSString*) callId {
@ -1461,6 +1561,14 @@ static int comp_call_id(const LinphoneCall* call , const char *callid) {
return YES;
}
- (void)playMessageSound {
BOOL success = [self.messagePlayer play];
if( !success ){
Linphone_err(@"Could not play the message sound");
}
AudioServicesPlaySystemSound([LinphoneManager instance].sounds.vibrate);
}
static int comp_call_state_paused (const LinphoneCall* call, const void* param) {
return linphone_call_get_state(call) != LinphoneCallPaused;
}
@ -1544,7 +1652,6 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param)
linphone_core_set_network_reachable(theLinphoneCore, FALSE);
return YES;
}
[self destroyLibLinphone];
return NO;
} else
@ -1701,7 +1808,7 @@ static void audioRouteChangeListenerCallback (
#pragma mark - Call Functions
- (void)acceptCall:(LinphoneCall *)call {
LinphoneCallParams* lcallParams = linphone_core_create_default_call_parameters(theLinphoneCore);
LinphoneCallParams* lcallParams = linphone_core_create_call_params(theLinphoneCore,call);
if([self lpConfigBoolForKey:@"edge_opt_preference"]) {
bool low_bandwidth = self.network == network_2g;
if(low_bandwidth) {
@ -1710,12 +1817,6 @@ static void audioRouteChangeListenerCallback (
linphone_call_params_enable_low_bandwidth(lcallParams, low_bandwidth);
}
// workaround for video policy not correctly updated for automatic accept
BOOL video = linphone_call_params_video_enabled(lcallParams);
const LinphoneVideoPolicy* policy = linphone_core_get_video_policy(theLinphoneCore);
video &= policy->automatically_accept;
linphone_call_params_enable_video(lcallParams, video);
linphone_core_accept_call_with_params(theLinphoneCore,call, lcallParams);
}
@ -1759,8 +1860,22 @@ static void audioRouteChangeListenerCallback (
}
LinphoneCall* call=NULL;
BOOL addressIsASCII = [address canBeConvertedToEncoding:[NSString defaultCStringEncoding]];
if ([address length] == 0) return; //just return
if ([address hasPrefix:@"sip:"] || [address hasPrefix:@"sips:"]) {
if( !addressIsASCII ){
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid SIP address",nil)
message:NSLocalizedString(@"The address should only contain ASCII data",nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Continue",nil)
otherButtonTitles:nil];
[error show];
[error release];
} else if ([address hasPrefix:@"sip:"] || [address hasPrefix:@"sips:"]) {
LinphoneAddress* linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
if(displayName!=nil) {
linphone_address_set_display_name(linphoneAddress,[displayName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
@ -1773,7 +1888,9 @@ static void audioRouteChangeListenerCallback (
call=linphone_core_invite_address_with_params(theLinphoneCore, linphoneAddress, lcallParams);
}
linphone_address_destroy(linphoneAddress);
} 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
@ -1781,7 +1898,8 @@ static void audioRouteChangeListenerCallback (
otherButtonTitles:nil];
[error show];
[error release];
} else {
} else {
char normalizedUserName[256];
LinphoneAddress* linphoneAddress = linphone_address_new(linphone_core_get_identity(theLinphoneCore));
linphone_proxy_config_normalize_number(proxyCfg,[address cStringUsingEncoding:[NSString defaultCStringEncoding]],normalizedUserName,sizeof(normalizedUserName));
@ -1799,9 +1917,14 @@ static void audioRouteChangeListenerCallback (
linphone_address_destroy(linphoneAddress);
}
if (call) {
LinphoneCallAppData* data = [[LinphoneCallAppData alloc] init];
data->videoRequested = linphone_call_params_video_enabled(lcallParams); /* will be used later to notify user if video was not activated because of the linphone core*/
linphone_call_set_user_pointer(call, data);
// The LinphoneCallAppData object should be set on call creation with callback
// - (void)onCall:StateChanged:withMessage:. If not, we are in big trouble and expect it to crash
// We are NOT responsible for creating the AppData.
LinphoneCallAppData* data=(LinphoneCallAppData*)linphone_call_get_user_pointer(call);
if (data==nil)
[LinphoneLogger log:LinphoneLoggerError format:@"New call instanciated but app data was not set. Expect it to crash."];
/* will be used later to notify user if video was not activated because of the linphone core*/
data->videoRequested = linphone_call_params_video_enabled(lcallParams);
}
linphone_call_params_destroy(lcallParams);
}
@ -1818,21 +1941,19 @@ static void audioRouteChangeListenerCallback (
pushNotificationToken = nil;
}
if(apushNotificationToken != nil) {
pushNotificationToken = [apushNotificationToken retain];
}
if([LinphoneManager isLcReady]) {
LinphoneProxyConfig *cfg=nil;
linphone_core_get_default_proxy(theLinphoneCore, &cfg);
if (cfg) {
linphone_proxy_config_edit(cfg);
[self addPushTokenToProxyConfig: cfg];
linphone_proxy_config_done(cfg);
}
}
if(apushNotificationToken != nil) {
pushNotificationToken = [apushNotificationToken retain];
}
LinphoneProxyConfig *cfg=nil;
linphone_core_get_default_proxy(theLinphoneCore, &cfg);
if (cfg ) {
linphone_proxy_config_edit(cfg);
[self configurePushTokenForProxyConfig: cfg];
linphone_proxy_config_done(cfg);
}
}
- (void)addPushTokenToProxyConfig:(LinphoneProxyConfig*)proxyCfg{
- (void)configurePushTokenForProxyConfig:(LinphoneProxyConfig*)proxyCfg{
NSData *tokenData = pushNotificationToken;
if(tokenData != nil && [self lpConfigBoolForKey:@"pushnotification_preference"]) {
const unsigned char *tokenBuffer = [tokenData bytes];
@ -1851,10 +1972,15 @@ static void audioRouteChangeListenerCallback (
linphone_proxy_config_set_contact_uri_parameters(proxyCfg, [params UTF8String]);
linphone_proxy_config_set_contact_parameters(proxyCfg, NULL);
}
} else {
// no push token:
linphone_proxy_config_set_contact_uri_parameters(proxyCfg, NULL);
linphone_proxy_config_set_contact_parameters(proxyCfg, NULL);
}
}
#pragma mark - Misc Functions
+ (NSString*)bundleFile:(NSString*)file {
@ -1867,18 +1993,31 @@ static void audioRouteChangeListenerCallback (
return [documentsPath stringByAppendingPathComponent:file];
}
+ (int)unreadMessageCount {
int count = 0;
MSList* rooms = linphone_core_get_chat_rooms([LinphoneManager getLc]);
MSList* item = rooms;
while (item) {
LinphoneChatRoom* room = (LinphoneChatRoom*)item->data;
if( room ){
count += linphone_chat_room_get_unread_messages_count(room);
}
item = item->next;
+ (NSString*)cacheDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [paths objectAtIndex:0];
BOOL isDir = NO;
NSError *error;
// cache directory must be created if not existing
if (! [[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&isDir] && isDir == NO) {
[[NSFileManager defaultManager] createDirectoryAtPath:cachePath withIntermediateDirectories:NO attributes:nil error:&error];
}
return count;
return cachePath;
}
+ (int)unreadMessageCount {
int count = 0;
MSList* rooms = linphone_core_get_chat_rooms([LinphoneManager getLc]);
MSList* item = rooms;
while (item) {
LinphoneChatRoom* room = (LinphoneChatRoom*)item->data;
if( room ){
count += linphone_chat_room_get_unread_messages_count(room);
}
item = item->next;
}
return count;
}
+ (BOOL)copyFile:(NSString*)src destination:(NSString*)dst override:(BOOL)override {
@ -1911,17 +2050,26 @@ static void audioRouteChangeListenerCallback (
- (void)configureVbrCodecs{
PayloadType *pt;
int bitrate=lp_config_get_int(configDb,"audio","codec_bitrate_limit",kLinphoneAudioVbrCodecDefaultBitrate);/*default value is in linphonerc or linphonerc-factory*/
pt=linphone_core_find_payload_type(theLinphoneCore, "opus", 48000, -1);
if (pt){
linphone_core_set_payload_type_bitrate(theLinphoneCore,pt,bitrate);
}
pt=linphone_core_find_payload_type(theLinphoneCore, "mpeg4-generic", 44100, -1);
if (pt){
linphone_core_set_payload_type_bitrate(theLinphoneCore,pt,bitrate);
}
pt=linphone_core_find_payload_type(theLinphoneCore, "mpeg4-generic", 22050, -1);
if (pt){
linphone_core_set_payload_type_bitrate(theLinphoneCore,pt,bitrate);
const MSList *audio_codecs = linphone_core_get_audio_codecs(theLinphoneCore);
const MSList* codec = audio_codecs;
while (codec) {
pt = codec->data;
if( linphone_core_payload_type_is_vbr(theLinphoneCore, pt) ) {
linphone_core_set_payload_type_bitrate(theLinphoneCore, pt, bitrate);
}
codec = codec->next;
}
}
-(void)setLogsEnabled:(BOOL)enabled {
if (enabled) {
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);
linphone_core_enable_log_collection(enabled);
} else {
linphone_core_enable_log_collection(enabled);
linphone_core_disable_logs();
}
}
@ -1950,7 +2098,8 @@ static void audioRouteChangeListenerCallback (
NSData* data = [NSJSONSerialization dataWithJSONObject:appDataDict options:0 error:nil];
NSString* appdataJSON = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
linphone_chat_message_set_appdata(msg, [appdataJSON UTF8String] );
linphone_chat_message_set_appdata(msg, [appdataJSON UTF8String]);
[appdataJSON release];
}
#pragma mark - LPConfig Functions
@ -1987,7 +2136,7 @@ static void audioRouteChangeListenerCallback (
- (void)lpConfigSetInt:(NSInteger)value forKey:(NSString*)key forSection:(NSString *)section {
if (!key) return;
lp_config_set_int(configDb, [section UTF8String], [key UTF8String], value );
lp_config_set_int(configDb, [section UTF8String], [key UTF8String], (int)value );
}
- (NSInteger)lpConfigIntForKey:(NSString*)key {

Binary file not shown.

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6245" systemVersion="13F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1536" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6238"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UICallBar">
@ -14,6 +14,7 @@
<outlet property="fourButton" destination="69" id="77"/>
<outlet property="hangupButton" destination="7" id="29"/>
<outlet property="landscapeView" destination="100" id="137"/>
<outlet property="leftPadding" destination="ft8-yH-2Ta" id="zp9-XP-bDv"/>
<outlet property="microButton" destination="11" id="14"/>
<outlet property="nineButton" destination="66" id="78"/>
<outlet property="oneButton" destination="73" id="79"/>
@ -24,6 +25,7 @@
<outlet property="padView" destination="31" id="45"/>
<outlet property="pauseButton" destination="8" id="15"/>
<outlet property="portraitView" destination="4" id="138"/>
<outlet property="rightPadding" destination="145" id="cgI-HK-3gA"/>
<outlet property="routesBluetoothButton" destination="174" id="203"/>
<outlet property="routesButton" destination="164" id="202"/>
<outlet property="routesReceiverButton" destination="169" id="204"/>
@ -306,13 +308,13 @@
<rect key="frame" x="0.0" y="325" width="320" height="135"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="100" contentMode="scaleToFill" image="callbar_left_padding.png" id="146" userLabel="leftPadding">
<rect key="frame" x="-44" y="-8" width="44" height="90"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" tag="60" contentMode="scaleToFill" image="incall_padding_left.png" id="ft8-yH-2Ta" userLabel="leftPadding">
<rect key="frame" x="-47" y="-11" width="47" height="146"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" tag="101" contentMode="scaleToFill" image="callbar_right_padding.png" id="145" userLabel="rightPadding">
<rect key="frame" x="320" y="-8" width="44" height="90"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<imageView userInteractionEnabled="NO" tag="61" contentMode="scaleToFill" image="incall_padding_right.png" id="145" userLabel="rightPadding">
<rect key="frame" x="320" y="-11" width="47" height="146"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</imageView>
<button opaque="NO" tag="19" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="12" userLabel="videoButton" customClass="UIVideoButton">
<rect key="frame" x="0.0" y="0.0" width="80" height="67"/>
@ -727,13 +729,13 @@
<rect key="frame" x="0.0" y="238" width="480" height="82"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="100" contentMode="scaleToFill" image="callbar_left_padding.png" id="143" userLabel="leftPadding">
<rect key="frame" x="-44" y="-8" width="44" height="90"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<imageView userInteractionEnabled="NO" tag="60" contentMode="scaleToFill" image="incall_padding_left_landscape.png" id="143" userLabel="leftPadding">
<rect key="frame" x="-128" y="-24" width="128" height="106"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" tag="101" contentMode="scaleToFill" image="callbar_right_padding.png" id="144" userLabel="rightPadding">
<rect key="frame" x="480" y="-8" width="44" height="90"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<imageView userInteractionEnabled="NO" tag="61" contentMode="scaleToFill" image="incall_padding_right_landscape.png" id="144" userLabel="rightPadding">
<rect key="frame" x="480" y="-24" width="128" height="106"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</imageView>
<button opaque="NO" tag="19" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="113" userLabel="videoButton" customClass="UIVideoButton">
<rect key="frame" x="65" y="0.0" width="65" height="82"/>
@ -902,11 +904,10 @@
<nil key="simulatedStatusBarMetrics"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="295" y="-146"/>
</view>
</objects>
<resources>
<image name="callbar_left_padding.png" width="88" height="180"/>
<image name="callbar_right_padding.png" width="88" height="180"/>
<image name="conference_default.png" width="209" height="136"/>
<image name="conference_default_landscape.png" width="130" height="163"/>
<image name="conference_over.png" width="209" height="136"/>
@ -923,6 +924,10 @@
<image name="hangup_default_landscape.png" width="180" height="163"/>
<image name="hangup_over.png" width="222" height="136"/>
<image name="hangup_over_landscape.png" width="180" height="163"/>
<image name="incall_padding_left.png" width="94" height="292"/>
<image name="incall_padding_left_landscape.png" width="256" height="210"/>
<image name="incall_padding_right.png" width="94" height="292"/>
<image name="incall_padding_right_landscape.png" width="256" height="210"/>
<image name="micro_off_default.png" width="160" height="134"/>
<image name="micro_off_default_landscape.png" width="130" height="163"/>
<image name="micro_off_disabled.png" width="160" height="134"/>

Binary file not shown.

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="6245" systemVersion="13F34" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1536" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6238"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UICallBar">
@ -14,6 +14,7 @@
<outlet property="fourButton" destination="22" id="68"/>
<outlet property="hangupButton" destination="11" id="69"/>
<outlet property="landscapeView" destination="2" id="70"/>
<outlet property="leftPadding" destination="Htc-7i-IYY" id="zVJ-JC-Di6"/>
<outlet property="microButton" destination="16" id="71"/>
<outlet property="nineButton" destination="27" id="72"/>
<outlet property="oneButton" destination="19" id="73"/>
@ -24,6 +25,7 @@
<outlet property="padView" destination="5" id="78"/>
<outlet property="pauseButton" destination="13" id="79"/>
<outlet property="portraitView" destination="3" id="80"/>
<outlet property="rightPadding" destination="aXO-Ng-LZe" id="f1h-to-gx6"/>
<outlet property="sevenButton" destination="25" id="81"/>
<outlet property="sharpButton" destination="30" id="82"/>
<outlet property="sixButton" destination="24" id="83"/>
@ -347,6 +349,12 @@
<state key="selected" image="dialer_alt_back_default_landscape.png"/>
<state key="highlighted" image="dialer_alt_over_landscape.png"/>
</button>
<imageView hidden="YES" userInteractionEnabled="NO" tag="61" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="xvD-yI-e1g" userLabel="leftPadding">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView hidden="YES" userInteractionEnabled="NO" tag="62" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="8M5-a6-pwT" userLabel="rightPadding">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
@ -693,6 +701,12 @@
<action selector="onPadClick:" destination="-1" eventType="touchUpInside" id="92"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" tag="61" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="Htc-7i-IYY" userLabel="leftPadding">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" tag="62" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="aXO-Ng-LZe" userLabel="rightPadding">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>

Binary file not shown.

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="5053" systemVersion="13C64" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1536" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UICallCell">
@ -19,14 +19,12 @@
<outlet property="audioUploadBandwidthLabel" destination="90" id="121"/>
<outlet property="avatarImage" destination="29" id="34"/>
<outlet property="avatarView" destination="31" id="41"/>
<outlet property="backgroundView" destination="45" id="46"/>
<outlet property="headerBackgroundHighlightImage" destination="56" id="59"/>
<outlet property="headerBackgroundImage" destination="52" id="54"/>
<outlet property="headerView" destination="36" id="42"/>
<outlet property="otherView" destination="77" id="78"/>
<outlet property="pauseButton" destination="47" id="48"/>
<outlet property="removeButton" destination="49" id="50"/>
<outlet property="selectedBackgroundView" destination="45" id="58"/>
<outlet property="stateImage" destination="18" id="33"/>
<outlet property="stateLabel" destination="19" id="32"/>
<outlet property="videoCodecHeaderLabel" destination="105" id="122"/>
@ -47,7 +45,7 @@
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="16">
<rect key="frame" x="0.0" y="0.0" width="320" height="300"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" id="77" userLabel="otherView">
<rect key="frame" x="0.0" y="0.0" width="320" height="300"/>
@ -55,32 +53,11 @@
<subviews>
<view contentMode="scaleToFill" id="31" userLabel="avatarView">
<rect key="frame" x="0.0" y="63" width="320" height="237"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="44">
<rect key="frame" x="0.0" y="0.0" width="320" height="250"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="avatar_shadow.png" id="30" userLabel="avatarShadowImage">
<rect key="frame" x="0.0" y="-15" width="320" height="262"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="avatar_unknown.png" id="29" userLabel="avatarImage">
<rect key="frame" x="80" y="2" width="160" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="avatar_unknown.png" id="29" userLabel="avatarImage">
<rect key="frame" x="80" y="0.0" width="160" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<accessibility key="accessibilityConfiguration" label="Contact's avatar">
<accessibilityTraits key="traits" none="YES" image="YES" notEnabled="YES"/>
@ -88,36 +65,35 @@
</accessibility>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="76" userLabel="audioStatsView">
<rect key="frame" x="0.0" y="63" width="320" height="237"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="0.0" y="63" width="331" height="237"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Audio" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="95" userLabel="audioLabel">
<rect key="frame" x="10" y="21" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="15" y="21" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Audio section"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="22"/>
<color key="textColor" red="0.35686275360000003" green="0.3960784376" blue="0.43529412150000002" alpha="1" colorSpace="deviceRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" id="83" userLabel="audioCodecView">
<rect key="frame" x="10" y="50" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="10" y="50" width="310" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Codec:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="85" userLabel="audioCodecHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="60" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="SILK" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="84" userLabel="audioCodecLabel">
<rect key="frame" x="68" y="0.0" width="232" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="SILK" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="84" userLabel="audioCodecLabel">
<rect key="frame" x="68" y="0.0" width="242" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Audio codec">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
@ -128,21 +104,21 @@
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="89" userLabel="audioUploadBandwidthView">
<rect key="frame" x="10" y="80" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="10" y="80" width="310" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Upload bandwidth:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="91" userLabel="audioUploadBandwidthHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="2 KB/s" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="90" userLabel="audioUploadBandwidthLabel">
<rect key="frame" x="168" y="0.0" width="132" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="2 KB/s" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="90" userLabel="audioUploadBandwidthLabel">
<rect key="frame" x="168" y="0.0" width="142" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Audio upload bandwidth">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
@ -153,21 +129,21 @@
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="92" userLabel="audioDownloadBandwidthView">
<rect key="frame" x="10" y="110" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="10" y="110" width="310" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Download bandwidth:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="93" userLabel="audioDownloadBandwidthHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="182" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="10.0 KB/s" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="94" userLabel="audioDownloadBandwidthLabel">
<rect key="frame" x="190" y="0.0" width="110.00000000000001" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="10.0 KB/s" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="94" userLabel="audioDownloadBandwidthLabel">
<rect key="frame" x="190" y="0.0" width="120" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Video upload bandwidth">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
@ -178,21 +154,21 @@
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="96" userLabel="audioIceConnectivityView">
<rect key="frame" x="10" y="140" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="10" y="140" width="310" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="ICE connectivity:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="98" userLabel="audioIceConnectivityHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="142" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="not activated" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="97" userLabel="audioIceConnectivityLabel">
<rect key="frame" x="150" y="0.0" width="150" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="not activated" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="97" userLabel="audioIceConnectivityLabel">
<rect key="frame" x="150" y="0.0" width="160" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Audio ICE connectivity state">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
@ -206,33 +182,33 @@
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="99" userLabel="videoStatsView">
<rect key="frame" x="0.0" y="63" width="320" height="237"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="0.0" y="63" width="331" height="237"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Video" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="101" userLabel="videoLabel">
<rect key="frame" x="10" y="21" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="15" y="21" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Video section"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="22"/>
<color key="textColor" red="0.35686275360000003" green="0.3960784376" blue="0.43529412150000002" alpha="1" colorSpace="deviceRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" id="104" userLabel="videoCodecView">
<rect key="frame" x="78" y="23" width="232" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="10" y="50" width="310" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Codec:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="105" userLabel="videoCodecHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="60" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="SILK" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="106" userLabel="videoCodecLabel">
<rect key="frame" x="68" y="0.0" width="164" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="SILK" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="106" userLabel="videoCodecLabel">
<rect key="frame" x="68" y="0.0" width="242" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Video codec">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
@ -242,47 +218,22 @@
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="103" userLabel="videoUploadBandwidthView">
<rect key="frame" x="10" y="113" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Upload bandwidth:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="107" userLabel="videoUploadBandwidthHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="2 KB/s" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="108" userLabel="videoUploadBandwidthLabel">
<rect key="frame" x="168" y="0.0" width="132" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Video upload bandwidth">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="j5j-bZ-C2L" userLabel="videoSentSizeView">
<rect key="frame" x="10" y="50" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="10" y="80" width="310" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Size sent:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="6PM-O1-cYd" userLabel="videoSentSizeHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="320x240" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="CCZ-g0-5g1" userLabel="videoSentSizeLabel">
<rect key="frame" x="168" y="0.0" width="132" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="320x240" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="CCZ-g0-5g1" userLabel="videoSentSizeLabel">
<rect key="frame" x="168" y="0.0" width="142" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Video upload bandwidth">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
@ -293,21 +244,21 @@
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="6oX-23-Ivn" userLabel="videoRecvSizeView">
<rect key="frame" x="10" y="79" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="10" y="110" width="310" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Size received:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="nNJ-4U-pl2" userLabel="videoRecvSizeHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="320x240" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="RxS-YG-dqM" userLabel="videoRecvSizeLabel">
<rect key="frame" x="168" y="0.0" width="132" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="320x240" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="RxS-YG-dqM" userLabel="videoRecvSizeLabel">
<rect key="frame" x="168" y="0.0" width="142" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Video upload bandwidth">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
@ -317,22 +268,47 @@
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="102" userLabel="audioDownloadBandwidthView">
<rect key="frame" x="10" y="143" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view contentMode="scaleToFill" id="103" userLabel="videoUploadBandwidthView">
<rect key="frame" x="10" y="140" width="310" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Download bandwidth:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="110" userLabel="videoDownloadBandwidthHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="182" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Upload bandwidth:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="107" userLabel="videoUploadBandwidthHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="10.0 KB/s" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="109" userLabel="videoDownloadBandwidthLabel">
<rect key="frame" x="190" y="0.0" width="109.99999999999999" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="2 KB/s" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="108" userLabel="videoUploadBandwidthLabel">
<rect key="frame" x="168" y="0.0" width="142" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Video upload bandwidth">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="102" userLabel="videoDownloadBandwidthView">
<rect key="frame" x="10" y="170" width="310" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Download bandwidth:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="110" userLabel="videoDownloadBandwidthHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="182" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="10.0 KB/s" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="109" userLabel="videoDownloadBandwidthLabel">
<rect key="frame" x="190" y="0.0" width="120" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Audio download bandwidth">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
@ -342,22 +318,22 @@
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view contentMode="scaleToFill" id="100" userLabel="audioIceConnectivityView">
<rect key="frame" x="10" y="173" width="300" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view contentMode="scaleToFill" id="100" userLabel="videoIceConnectivityView">
<rect key="frame" x="10" y="200" width="310" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="ICE connectivity:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="111" userLabel="videoIceConnectivityHeaderLabel">
<rect key="frame" x="0.0" y="0.0" width="142" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="not activated" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="112" userLabel="videoIceConnectivityLabel">
<rect key="frame" x="150" y="0.0" width="150" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="not activated" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="112" userLabel="videoIceConnectivityLabel">
<rect key="frame" x="150" y="0.0" width="160" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Video ICE connectivity state">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
@ -460,15 +436,11 @@
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view autoresizesSubviews="NO" contentMode="scaleToFill" id="45" userLabel="background">
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
</view>
</objects>
<resources>
<image name="avatar_shadow.png" width="640" height="523"/>
<image name="avatar_unknown.png" width="320" height="339"/>
<image name="call_state_delete_default.png" width="43" height="43"/>
<image name="call_state_delete_over.png" width="43" height="43"/>
@ -477,4 +449,9 @@
<image name="call_state_play_over.png" width="43" height="46"/>
<image name="cell_call_first.png" width="640" height="125"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

Binary file not shown.

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1072" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIChatCell">
@ -27,7 +27,7 @@
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="John" lineBreakMode="tailTruncation" minimumFontSize="10" adjustsFontSizeToFit="NO" id="20" userLabel="addressLabel">
<rect key="frame" x="62" y="2" width="218" height="38"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Firstname"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="25"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
@ -35,7 +35,7 @@
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="This is a message" lineBreakMode="tailTruncation" numberOfLines="2" minimumFontSize="10" adjustsFontSizeToFit="NO" id="21" userLabel="chatContentLabel">
<rect key="frame" x="62" y="39" width="218" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Firstname"/>
<accessibility key="accessibilityConfiguration" label="Message"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
@ -51,6 +51,7 @@
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="3" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" id="41" userLabel="unreadMessageLabel">
<rect key="frame" x="12" y="10" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Unread message number"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
@ -61,6 +62,7 @@
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="32" userLabel="deleteButton">
<rect key="frame" x="276" y="8" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<inset key="imageEdgeInsets" minX="11" minY="11" maxX="11" maxY="11"/>
<state key="normal" image="list_delete_default.png">
@ -73,6 +75,8 @@
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
</view>
</objects>
<resources>
@ -81,4 +85,9 @@
<image name="list_delete_default.png" width="45" height="45"/>
<image name="list_delete_over.png" width="45" height="45"/>
</resources>
</document>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1280" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIHistoryCell">
@ -21,11 +21,14 @@
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" id="6" userLabel="imageView">
<rect key="frame" x="10" y="8" width="27" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Call type">
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="John" lineBreakMode="tailTruncation" minimumFontSize="10" adjustsFontSizeToFit="NO" id="5" userLabel="displayNameLabel">
<rect key="frame" x="45" y="0.0" width="236" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Firstname"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="25"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
@ -58,6 +61,8 @@
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
</view>
</objects>
<resources>
@ -66,4 +71,9 @@
<image name="list_details_default.png" width="45" height="45"/>
<image name="list_details_over.png" width="45" height="45"/>
</resources>
</document>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

Binary file not shown.

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="5056" systemVersion="13C1021" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment defaultVersion="1536" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIMainBar">
@ -21,19 +21,24 @@
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view autoresizesSubviews="NO" contentMode="scaleToFill" id="3">
<view contentMode="scaleToFill" id="3">
<rect key="frame" x="0.0" y="0.0" width="320" height="77"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<view hidden="YES" autoresizesSubviews="NO" opaque="NO" clearsContextBeforeDrawing="NO" userInteractionEnabled="NO" tag="-1" contentMode="scaleToFill" id="4" userLabel="mask">
<rect key="frame" x="0.0" y="11" width="320" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view hidden="YES" autoresizesSubviews="NO" opaque="NO" clearsContextBeforeDrawing="NO" userInteractionEnabled="NO" tag="-1" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4" userLabel="mask">
<rect key="frame" x="0.0" y="12" width="320" height="65"/>
<color key="backgroundColor" red="0.0" green="1" blue="0.090924573910000001" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="65" id="SfG-nT-bfE"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="6" userLabel="history">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6" userLabel="history">
<rect key="frame" x="0.0" y="0.0" width="64" height="77"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="History"/>
<constraints>
<constraint firstAttribute="height" constant="77" id="9fJ-Bx-Z87"/>
<constraint firstAttribute="width" constant="64" id="dSE-Nc-AQX"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="40" maxX="0.0" maxY="0.0"/>
<state key="normal" title="History" backgroundImage="history_default.png">
@ -50,31 +55,13 @@
<action selector="onHistoryClick:" destination="-1" eventType="touchUpInside" id="22"/>
</connections>
</button>
<view hidden="YES" autoresizesSubviews="NO" userInteractionEnabled="NO" contentMode="scaleToFill" id="32" userLabel="historyNotificationView">
<rect key="frame" x="38" y="1" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="history_notification.png" id="33" userLabel="historyNotificationImage">
<rect key="frame" x="0.0" y="0.0" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="99" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="34" userLabel="historyNotificationLabel">
<rect key="frame" x="2" y="2" width="17" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<accessibility key="accessibilityConfiguration" label="Missed call(s)">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="8" userLabel="contacts">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8" userLabel="contacts">
<rect key="frame" x="64" y="0.0" width="64" height="77"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contacts"/>
<constraints>
<constraint firstAttribute="width" constant="64" id="7qG-OX-ocj"/>
<constraint firstAttribute="height" constant="77" id="AaL-yt-Hnd"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="40" maxX="0.0" maxY="0.0"/>
<state key="normal" title="Contacts" backgroundImage="contacts_default.png">
@ -91,10 +78,13 @@
<action selector="onContactsClick:" destination="-1" eventType="touchUpInside" id="23"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="9" userLabel="settings">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9" userLabel="settings">
<rect key="frame" x="256" y="0.0" width="64" height="77"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Settings"/>
<constraints>
<constraint firstAttribute="width" constant="64" id="50o-3P-EEl"/>
<constraint firstAttribute="height" constant="77" id="cUb-Ax-J5i"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="40" maxX="0.0" maxY="0.0"/>
<state key="normal" title="Settings" backgroundImage="settings_default.png">
@ -111,10 +101,13 @@
<action selector="onSettingsClick:" destination="-1" eventType="touchUpInside" id="25"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="7" userLabel="dialer">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7" userLabel="dialer">
<rect key="frame" x="128" y="0.0" width="64" height="77"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Dialer"/>
<constraints>
<constraint firstAttribute="width" constant="64" id="Kyv-1i-fVw"/>
<constraint firstAttribute="height" constant="77" id="hR6-kA-HxY"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="dialer_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
@ -125,10 +118,13 @@
<action selector="onDialerClick:" destination="-1" eventType="touchUpInside" id="24"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="5" userLabel="chat">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5" userLabel="chat">
<rect key="frame" x="192" y="0.0" width="64" height="77"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Chat"/>
<constraints>
<constraint firstAttribute="width" constant="64" id="eh4-r3-oxy"/>
<constraint firstAttribute="height" constant="77" id="gId-1A-3gt"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="40" maxX="0.0" maxY="0.0"/>
<state key="normal" title="Chat" backgroundImage="chat_default.png">
@ -145,29 +141,113 @@
<action selector="onChatClick:" destination="-1" eventType="touchUpInside" id="26"/>
</connections>
</button>
<view hidden="YES" autoresizesSubviews="NO" userInteractionEnabled="NO" contentMode="scaleToFill" id="37" userLabel="chatNotificationView">
<rect key="frame" x="197" y="1" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view hidden="YES" autoresizesSubviews="NO" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="37" userLabel="chatNotificationView">
<rect key="frame" x="235" y="0.0" width="21" height="21"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="history_notification.png" id="39" userLabel="chatNotificationImage">
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="history_notification.png" translatesAutoresizingMaskIntoConstraints="NO" id="39" userLabel="chatNotificationImage">
<rect key="frame" x="0.0" y="0.0" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="99" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="38" userLabel="chatNotificationLabel">
<rect key="frame" x="2" y="2" width="17" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="99" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="38" userLabel="chatNotificationLabel">
<rect key="frame" x="3" y="2" width="16" height="17"/>
<accessibility key="accessibilityConfiguration" label="Missed message(s)">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<constraints>
<constraint firstAttribute="height" constant="17" id="0L7-q4-XAQ"/>
<constraint firstAttribute="width" constant="16" id="jXP-Y5-d8a"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="centerY" secondItem="38" secondAttribute="centerY" id="AqH-xS-ee0"/>
<constraint firstAttribute="width" constant="21" id="CKe-U0-pTJ"/>
<constraint firstAttribute="centerX" secondItem="39" secondAttribute="centerX" id="DJZ-vG-EZ9"/>
<constraint firstAttribute="centerX" secondItem="38" secondAttribute="centerX" id="PyV-QG-q3f"/>
<constraint firstItem="39" firstAttribute="height" secondItem="37" secondAttribute="height" id="Uzu-M2-lWM"/>
<constraint firstAttribute="height" constant="21" id="bSp-VO-Ar7"/>
<constraint firstAttribute="centerY" secondItem="39" secondAttribute="centerY" id="cYa-kU-nJs"/>
<constraint firstItem="39" firstAttribute="width" secondItem="37" secondAttribute="width" id="yxe-m3-Pcu"/>
</constraints>
</view>
<view autoresizesSubviews="NO" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="32" userLabel="historyNotificationView">
<rect key="frame" x="43" y="0.0" width="21" height="21"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="history_notification.png" translatesAutoresizingMaskIntoConstraints="NO" id="33" userLabel="historyNotificationImage">
<rect key="frame" x="0.0" y="0.0" width="21" height="21"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="99" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="34" userLabel="historyNotificationLabel">
<rect key="frame" x="3" y="2" width="16" height="17"/>
<accessibility key="accessibilityConfiguration" label="Missed call(s)">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<constraints>
<constraint firstAttribute="height" constant="17" id="POi-z8-SlR"/>
<constraint firstAttribute="width" constant="16" id="dgV-A5-wuu"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="4T8-IM-ass"/>
<constraint firstAttribute="centerY" secondItem="33" secondAttribute="centerY" id="LTt-9K-g3a"/>
<constraint firstAttribute="centerX" secondItem="34" secondAttribute="centerX" id="Lih-Vg-mnM"/>
<constraint firstAttribute="centerX" secondItem="33" secondAttribute="centerX" id="Px6-nJ-aI7"/>
<constraint firstAttribute="centerY" secondItem="34" secondAttribute="centerY" id="aCW-40-4oh"/>
<constraint firstItem="33" firstAttribute="height" secondItem="32" secondAttribute="height" id="jJA-x1-0xU"/>
<constraint firstItem="33" firstAttribute="width" secondItem="32" secondAttribute="width" id="shb-FE-cRF"/>
<constraint firstAttribute="width" constant="21" id="tMw-Sg-MKB"/>
</constraints>
</view>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="dialer_padding_left.png" translatesAutoresizingMaskIntoConstraints="NO" id="f0B-Rk-Uez">
<rect key="frame" x="-47" y="-8" width="47" height="85"/>
<constraints>
<constraint firstAttribute="height" constant="85" id="Ce2-oh-cXP"/>
<constraint firstAttribute="width" constant="47" id="hvC-cr-MbF"/>
</constraints>
</imageView>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="dialer_padding_right.png" translatesAutoresizingMaskIntoConstraints="NO" id="if3-GT-4eC">
<rect key="frame" x="320" y="-8" width="47" height="85"/>
<constraints>
<constraint firstAttribute="width" constant="47" id="Ez5-zh-daE"/>
<constraint firstAttribute="height" constant="85" id="liI-Np-MjS"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" red="0.0" green="1" blue="0.19194547549999999" alpha="0.0" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstItem="4" firstAttribute="leading" secondItem="3" secondAttribute="leading" id="23R-LR-WSH"/>
<constraint firstAttribute="bottom" secondItem="f0B-Rk-Uez" secondAttribute="bottom" id="5jk-rI-3ek"/>
<constraint firstAttribute="bottom" secondItem="if3-GT-4eC" secondAttribute="bottom" id="BMD-5G-aiP"/>
<constraint firstItem="32" firstAttribute="trailing" secondItem="6" secondAttribute="trailing" id="KAR-Oc-g9D"/>
<constraint firstItem="if3-GT-4eC" firstAttribute="leading" secondItem="9" secondAttribute="trailing" id="Npd-ac-VuD"/>
<constraint firstItem="7" firstAttribute="leading" secondItem="8" secondAttribute="trailing" id="P0e-Vb-oo3"/>
<constraint firstItem="5" firstAttribute="leading" secondItem="7" secondAttribute="trailing" id="Q0Q-KR-hwu"/>
<constraint firstItem="5" firstAttribute="top" secondItem="37" secondAttribute="top" id="QTf-I4-aYm"/>
<constraint firstAttribute="bottom" secondItem="7" secondAttribute="bottom" id="RSs-eA-XI3"/>
<constraint firstItem="8" firstAttribute="leading" secondItem="6" secondAttribute="trailing" id="Tim-pC-QPd"/>
<constraint firstAttribute="bottom" secondItem="5" secondAttribute="bottom" id="UNn-fP-Bhi"/>
<constraint firstAttribute="bottom" secondItem="8" secondAttribute="bottom" id="ZXj-CV-9DA"/>
<constraint firstItem="6" firstAttribute="leading" secondItem="f0B-Rk-Uez" secondAttribute="trailing" id="buH-90-U2H"/>
<constraint firstAttribute="trailing" secondItem="4" secondAttribute="trailing" id="bz1-ui-hrk"/>
<constraint firstItem="6" firstAttribute="top" secondItem="32" secondAttribute="top" id="dEI-FQ-VES"/>
<constraint firstAttribute="centerX" secondItem="4" secondAttribute="centerX" id="jmU-VM-s9L"/>
<constraint firstItem="5" firstAttribute="trailing" secondItem="37" secondAttribute="trailing" id="kGi-dF-bTb"/>
<constraint firstItem="9" firstAttribute="leading" secondItem="5" secondAttribute="trailing" id="tw3-7Q-WKv"/>
<constraint firstAttribute="bottom" secondItem="6" secondAttribute="bottom" id="umW-rl-qXm"/>
<constraint firstAttribute="centerX" secondItem="7" secondAttribute="centerX" id="wni-ky-koR"/>
<constraint firstAttribute="bottom" secondItem="9" secondAttribute="bottom" id="znG-Zq-s5I"/>
<constraint firstAttribute="bottom" secondItem="4" secondAttribute="bottom" id="zvN-5z-2QF"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="988" y="613.5"/>
</view>
</objects>
<resources>
@ -179,6 +259,8 @@
<image name="contacts_selected.png" width="128" height="154"/>
<image name="dialer_default.png" width="128" height="154"/>
<image name="dialer_over.png" width="128" height="154"/>
<image name="dialer_padding_left.png" width="94" height="170"/>
<image name="dialer_padding_right.png" width="94" height="170"/>
<image name="dialer_selected.png" width="128" height="154"/>
<image name="history_default.png" width="128" height="154"/>
<image name="history_notification.png" width="43" height="43"/>
@ -188,4 +270,9 @@
<image name="settings_over.png" width="128" height="154"/>
<image name="settings_selected.png" width="128" height="154"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,24 @@
/* UIButtonShrinkable
*
* 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 <Foundation/Foundation.h>
@interface UIButtonShrinkable : UIButton
@end

View file

@ -0,0 +1,34 @@
/* UIButtonShrinkable
*
* 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 "UIButtonShrinkable.h"
@implementation UIButtonShrinkable : UIButton
- (instancetype)init {
self = [super init];
if (self) {
// automatically adjust title to fit available width
[self.titleLabel setAdjustsFontSizeToFitWidth:TRUE];
}
return self;
}
@end

View file

@ -48,6 +48,10 @@
@property (nonatomic, retain) IBOutlet UIButton* optionsTransferButton;
@property (nonatomic, retain) IBOutlet UIToggleButton* dialerButton;
@property (nonatomic, retain) IBOutlet UIImageView* leftPadding;
@property (nonatomic, retain) IBOutlet UIImageView* rightPadding;
@property (nonatomic, retain) IBOutlet UIDigitButton* oneButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* twoButton;
@property (nonatomic, retain) IBOutlet UIDigitButton* threeButton;

View file

@ -151,7 +151,16 @@
[LinphoneUtils buttonFixStates:videoButton];
[LinphoneUtils buttonFixStates:videoButtonLandscape];
}
{
UIImageView* leftPaddingLandscape = (UIImageView*)[landscapeView viewWithTag:self.leftPadding.tag];
leftPaddingLandscape.image =[UIImage imageNamed:@"incall_padding_left_landscape.png"];
}
{
UIImageView* rightPaddingLandscape = (UIImageView*)[landscapeView viewWithTag:self.rightPadding.tag];
rightPaddingLandscape.image = [UIImage imageNamed:@"incall_padding_right_landscape.png"];
}
{
UIButton *speakerButtonLandscape = (UIButton*) [landscapeView viewWithTag:[speakerButton tag]];
// Set selected+disabled background: IB lack !
@ -289,10 +298,6 @@
#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];
@ -339,10 +344,10 @@
}
switch(state) {
LinphoneCallEnd:
LinphoneCallError:
LinphoneCallIncoming:
LinphoneCallOutgoing:
case LinphoneCallEnd:
case LinphoneCallError:
case LinphoneCallIncoming:
case LinphoneCallOutgoing:
[self hidePad:TRUE];
[self hideOptions:TRUE];
[self hideRoutes:TRUE];
@ -568,7 +573,12 @@
[attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"];
if([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
[LinphoneUtils buttonMultiViewAddAttributes:attributes button:button];
[LinphoneUtils buttonMultiViewAddAttributes:attributes button:button];
} else if (view.tag ==self.leftPadding.tag || view.tag == self.rightPadding.tag){
UIImage* image = [(UIImageView*)view image];
if( image ){
[attributes setObject:image forKey:@"image"];
}
}
[attributes setObject:[NSNumber numberWithInteger:view.autoresizingMask] forKey:@"autoresizingMask"];
@ -581,6 +591,9 @@
if([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
[LinphoneUtils buttonMultiViewApplyAttributes:attributes button:button];
} else if (view.tag ==self.leftPadding.tag || view.tag == self.rightPadding.tag){
[(UIImageView*)view setImage:[attributes objectForKey:@"image"]];
}
view.autoresizingMask = [[attributes objectForKey:@"autoresizingMask"] integerValue];
}

View file

@ -37,7 +37,7 @@
self->call = acall;
image = [[UIImage imageNamed:@"avatar_unknown.png"] retain];
address = [@"Unknown" retain];
[self update];
[self update];
}
return self;
}
@ -147,7 +147,11 @@
options:nil];
if ([arrayOfViews count] >= 1) {
[self addSubview:[arrayOfViews objectAtIndex:0]];
//resize cell to match .nib size. It is needed when resized the cell to
//correctly adapt its height too
UIView *sub = ((UIView*)[arrayOfViews objectAtIndex:0]);
[self setFrame:CGRectMake(0, 0, sub.frame.size.width, sub.frame.size.height)];
[self addSubview:sub];
}
// Set selected+over background: IB lack !
[pauseButton setImage:[UIImage imageNamed:@"call_state_pause_over.png"]
@ -176,7 +180,12 @@
[UICallCell adaptSize:videoDownloadBandwidthHeaderLabel field:videoDownloadBandwidthLabel];
[UICallCell adaptSize:videoUploadBandwidthHeaderLabel field:videoUploadBandwidthLabel];
[UICallCell adaptSize:videoIceConnectivityHeaderLabel field:videoIceConnectivityLabel];
if ([LinphoneManager runningOnIpad]) {
[LinphoneUtils adjustFontSize:self.audioStatsView mult:2.22];
[LinphoneUtils adjustFontSize:self.videoStatsView mult:2.22];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification
@ -241,11 +250,6 @@
}
- (void)prepareForReuse {
}
#pragma mark - Properties Functions
- (void)setData:(UICallCellData *)adata {
@ -275,11 +279,11 @@
#pragma mark - Static Functions
+ (int)getMaximizedHeight {
return 300;
return [LinphoneManager runningOnIpad] ? 600 : 300;
}
+ (int)getMinimizedHeight {
return 63;
return [LinphoneManager runningOnIpad] ? 126 : 63;
}
+ (void)adaptSize:(UILabel*)label field:(UIView*)field {
@ -418,9 +422,12 @@
if(!data->minimize) {
CGRect frame = [self frame];
frame.size.height = [otherView frame].size.height;
frame.size.height = [UICallCell getMaximizedHeight];
[self setFrame:frame];
frame = otherView.frame;
frame.size.height = [UICallCell getMaximizedHeight];
[otherView setHidden:false];
otherView.frame = frame;
} else {
CGRect frame = [self frame];
frame.size.height = [headerView frame].size.height;
@ -519,7 +526,7 @@
if(parentTable != nil) {
NSIndexPath *index= [parentTable indexPathForCell:self];
if(index != nil) {
[parentTable reloadRowsAtIndexPaths:[[[NSArray alloc] initWithObjects:index, nil] autorelease] withRowAnimation:false];
[parentTable reloadRowsAtIndexPaths:@[index] withRowAnimation:false];
}
}
}

View file

@ -66,10 +66,6 @@
#pragma mark -
-(void) touchUp:(id) sender {
if(![LinphoneManager isLcReady]) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot tigger camswitch button: Linphone core not ready"];
return;
}
const char *currentCamId = (char*)linphone_core_get_video_device([LinphoneManager getLc]);
const char **cameras=linphone_core_get_video_devices([LinphoneManager getLc]);
const char *newCamId=NULL;

View file

@ -71,6 +71,11 @@
#pragma mark -
- (NSString *)accessibilityValue {
return [NSString stringWithFormat:@"%@ - %@ (%ld)", addressLabel.text, chatContentLabel.text, (long)[unreadMessageLabel.text integerValue]];
}
- (void)update {
NSString *displayName = nil;
UIImage *image = nil;
@ -97,15 +102,14 @@
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];
MSList* last_message_list = linphone_chat_room_get_history(chatRoom, 1);
LinphoneChatMessage* last_message = last_message_list? last_message_list->data : NULL;
LinphoneChatMessage* last_message = linphone_chat_room_get_user_data(chatRoom);
if( last_message ){
@ -135,7 +139,6 @@
[unreadMessageView setHidden:TRUE];
}
ms_list_free(last_message_list);
}
- (void)setEditing:(BOOL)editing {

View file

@ -45,7 +45,7 @@
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_MAX_WIDTH = 320.0f;
static const CGFloat CELL_MESSAGE_X_MARGIN = 26.0f + 10.0f;
static const CGFloat CELL_MESSAGE_Y_MARGIN = 36.0f;
static const CGFloat CELL_FONT_SIZE = 17.0f;
@ -105,6 +105,18 @@ static UIFont *CELL_FONT = nil;
}
+ (NSString*)decodeTextMessage:(const char*)text {
NSString* decoded = [NSString stringWithUTF8String:text];
if( decoded == nil ){
// couldn't decode the string as UTF8, do a lossy conversion
decoded = [NSString stringWithCString:text encoding:NSASCIIStringEncoding];
if( decoded == nil ){
decoded = @"(invalid string)";
}
}
return decoded;
}
- (void)update {
if(chat == nil) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room cell: null chat"];
@ -132,8 +144,8 @@ static UIFont *CELL_FONT = nil;
__block LinphoneChatMessage *achat = chat;
[[LinphoneManager instance].photoLibrary assetForURL:imageUrl resultBlock:^(ALAsset *asset) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) {
UIImage* image = [[UIImage alloc] initWithCGImage:[asset thumbnail]];
if(achat == self->chat) { //Avoid glitch and scrolling
UIImage* image = [[UIImage alloc] initWithCGImage:[asset thumbnail]];
dispatch_async(dispatch_get_main_queue(), ^{
[messageImageView setImage:image];
[messageImageView setFullImageUrl:asset];
@ -151,15 +163,19 @@ static UIFont *CELL_FONT = nil;
} else {
// simple text message
[messageText setHidden:FALSE];
if (text ){
if ( text ){
NSString* nstext = [UIChatRoomCell decodeTextMessage:text];
/* We need to use an attributed string here so that data detector don't mess
* with the text style. See http://stackoverflow.com/a/20669356 */
NSAttributedString* attr_text = [[NSAttributedString alloc]
initWithString:[NSString stringWithUTF8String:text]
initWithString:nstext
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17.0],
NSForegroundColorAttributeName:[UIColor darkGrayColor]}];
messageText.attributedText = attr_text;
[attr_text release];
} else {
messageText.text = @"";
}
@ -225,7 +241,7 @@ static UIFont *CELL_FONT = nil;
CGSize messageSize;
const char* url = linphone_chat_message_get_external_body_url(chat);
const char* text = linphone_chat_message_get_text(chat);
NSString* messageText = text ? [NSString stringWithUTF8String:text] : @"";
NSString* messageText = text ? [UIChatRoomCell decodeTextMessage:text] : @"";
if(url == nil) {
if(CELL_FONT == nil) {
CELL_FONT = [UIFont systemFontOfSize:CELL_FONT_SIZE];
@ -284,12 +300,14 @@ static UIFont *CELL_FONT = nil;
CGRect messageFrame = [bubbleView frame];
messageFrame.origin.y = ([innerView frame].size.height - messageFrame.size.height)/2;
if(!is_outgoing) { // Inverted
[backgroundImage setImage:[TUNinePatchCache imageOfSize:[backgroundImage bounds].size
forNinePatchNamed:@"chat_bubble_incoming"]];
UIImage* image = [UIImage imageNamed:@"chat_bubble_incoming"];
image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(26, 32, 34, 56)];
[backgroundImage setImage:image];
messageFrame.origin.y += 5;
} else {
[backgroundImage setImage:[TUNinePatchCache imageOfSize:[backgroundImage bounds].size
forNinePatchNamed:@"chat_bubble_outgoing"]];
UIImage* image = [UIImage imageNamed:@"chat_bubble_outgoing"];
image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(14, 15, 25, 40)];
[backgroundImage setImage:image];
messageFrame.origin.y -= 5;
}
[bubbleView setFrame:messageFrame];

View file

@ -177,7 +177,7 @@
oppositeFrame.size.width = frame.size.height;
// if we start in portrait, the landscape view must get the opposite height and width
if( portrait || [[UIDevice currentDevice].systemName floatValue] < 8 ){
if( portrait || [[UIDevice currentDevice].systemVersion floatValue] < 8 ){
Linphone_log(@"landscape get opposite: %@", NSStringFromCGSize(oppositeFrame.size));
[landscapeView setFrame:oppositeFrame];
} else {
@ -271,12 +271,10 @@
#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];
}
// Update rotation
UIInterfaceOrientation correctOrientation = [self getCorrectInterfaceOrientation:[[UIDevice currentDevice] orientation]];
if(currentOrientation != correctOrientation) {
[UICompositeViewController setOrientation:correctOrientation animated:currentOrientation != UIDeviceOrientationUnknown];
}
}
@ -354,25 +352,13 @@
+ (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];
}
}
}

View file

@ -70,6 +70,10 @@
[self setHighlighted:false animated:true];
}
- (NSString *)accessibilityValue {
return [NSString stringWithFormat:@"%@ %@", firstNameLabel.text, lastNameLabel.text];
}
- (void)update {
if(contact == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update contact cell: null contact"];
@ -83,13 +87,15 @@
CFStringRef lOrganization = ABRecordCopyValue(contact, kABPersonOrganizationProperty);
CFStringRef lLocalizedOrganization = (lOrganization != nil)?ABAddressBookCopyLocalizedLabel(lOrganization):nil;
if(lLocalizedFirstName != nil)
if(lLocalizedFirstName != nil){
[firstNameLabel setText: (NSString *)lLocalizedFirstName];
}
else
[firstNameLabel setText: @""];
if(lLocalizedLastName != nil)
if(lLocalizedLastName != nil){
[lastNameLabel setText: (NSString *)lLocalizedLastName];
}
else
[lastNameLabel setText: @""];

View file

@ -339,7 +339,8 @@
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if(contactDetailsDelegate != nil) {
[self performSelector:@selector(updateModification) withObject:nil afterDelay:0];
//add a mini delay to have the text updated BEFORE notifying the selector
[self performSelector:@selector(updateModification) withObject:nil afterDelay:0.1];
}
return YES;
}
@ -363,7 +364,8 @@
[LinphoneLogger logc:LinphoneLoggerWarning format:"Not valid UIEditableTableViewCell"];
}
if(contactDetailsDelegate != nil) {
[self performSelector:@selector(updateModification) withObject:nil afterDelay:0];
//add a mini delay to have the text updated BEFORE notifying the selector
[self performSelector:@selector(updateModification) withObject:nil afterDelay:0.1];
}
return TRUE;
}

View file

@ -69,11 +69,7 @@
#pragma mark - Actions Functions
- (void)touchDown:(id) sender {
if(![LinphoneManager isLcReady]) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot trigger digit button: Linphone core not ready"];
return;
}
if (addressField && (!dtmf || !linphone_core_in_call([LinphoneManager getLc]))) {
if (addressField && (!dtmf || !linphone_core_in_call([LinphoneManager getLc]))) {
NSString* newAddress = [NSString stringWithFormat:@"%@%c",addressField.text, digit];
[addressField setText:newAddress];
linphone_core_play_dtmf([LinphoneManager getLc], digit, -1);
@ -84,10 +80,6 @@
}
- (void)touchUp:(id) sender {
if(![LinphoneManager isLcReady]) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot trigger digit button: Linphone core not ready"];
return;
}
linphone_core_stop_dtmf([LinphoneManager getLc]);
}

View file

@ -26,4 +26,10 @@
@interface UIDigitButtonLongVoiceMail : UIDigitButton {
}
/* Returns TRUE if voice mail is configured in LinphoneCore */
- (BOOL) voiceMailEnabled;
/*! Automatically chooses the right icon depending on voice mail configured or not */
- (void) refreshUI;
@end

View file

@ -29,17 +29,27 @@
}
- (void)onLongTouch {
if(![LinphoneManager isLcReady]) {
[LinphoneLogger log:LinphoneLoggerWarning format:@"Cannot call voice mail: Linphone core not ready"];
return;
}
LinphoneManager* lm = [LinphoneManager instance];
NSString * voiceMailUri = [lm lpConfigStringForKey:@"voice_mail_uri" withDefault:NULL];
if (voiceMailUri != NULL) {
[lm call:voiceMailUri displayName:NSLocalizedString(@"Voice mail",nil) transfer:FALSE];
if ([self voiceMailEnabled]) {
LinphoneManager *lm = [LinphoneManager instance];
[lm call:[lm lpConfigStringForKey:@"voice_mail_uri"] displayName:NSLocalizedString(@"Voice mail",nil) transfer:FALSE];
}
}
- (BOOL) voiceMailEnabled {
NSString * voiceMailUri = [[LinphoneManager instance] lpConfigStringForKey:@"voice_mail_uri" withDefault:NULL];
return (voiceMailUri != NULL);
}
- (void)refreshUI {
NSString *name = @"numpad_one_";
if ([self voiceMailEnabled]) {
name = [name stringByAppendingString:@"voicemail_"];
}
[self setImage:[UIImage imageNamed:[name stringByAppendingString:@"default.png"]] forState: UIControlStateNormal];
[self setImage:[UIImage imageNamed:[name stringByAppendingString:@"over.png"]] forState: UIControlStateHighlighted];
}
@end

View file

@ -84,18 +84,14 @@
#pragma mark -
- (void)update {
if([LinphoneManager isLcReady]) {
LinphoneCore * lc = [LinphoneManager getLc];
if(linphone_core_get_calls_nb(lc) == 1 || // One call
linphone_core_get_current_call(lc) != NULL || // In call
linphone_core_is_in_conference(lc) || // In conference
(linphone_core_get_conference_size(lc) > 0 && [UIHangUpButton callCount:lc] == 0) // Only one conf
) {
[self setEnabled:true];
return;
}
} else {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update hangup button: Linphone core not ready"];
LinphoneCore * lc = [LinphoneManager getLc];
if(linphone_core_get_calls_nb(lc) == 1 || // One call
linphone_core_get_current_call(lc) != NULL || // In call
linphone_core_is_in_conference(lc) || // In conference
(linphone_core_get_conference_size(lc) > 0 && [UIHangUpButton callCount:lc] == 0) // Only one conf
) {
[self setEnabled:true];
return;
}
[self setEnabled:false];
}
@ -104,23 +100,19 @@
#pragma mark - Action Functions
-(void) touchUp:(id) sender {
if([LinphoneManager isLcReady]) {
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* currentcall = linphone_core_get_current_call(lc);
if (linphone_core_is_in_conference(lc) || // In conference
(linphone_core_get_conference_size(lc) > 0 && [UIHangUpButton callCount:lc] == 0) // Only one conf
) {
linphone_core_terminate_conference(lc);
} else if(currentcall != NULL) { // In a call
linphone_core_terminate_call(lc, currentcall);
} else {
const MSList* calls = linphone_core_get_calls(lc);
if (ms_list_size(calls) == 1) { // Only one call
linphone_core_terminate_call(lc,(LinphoneCall*)(calls->data));
}
}
LinphoneCore* lc = [LinphoneManager getLc];
LinphoneCall* currentcall = linphone_core_get_current_call(lc);
if (linphone_core_is_in_conference(lc) || // In conference
(linphone_core_get_conference_size(lc) > 0 && [UIHangUpButton callCount:lc] == 0) // Only one conf
) {
linphone_core_terminate_conference(lc);
} else if(currentcall != NULL) { // In a call
linphone_core_terminate_call(lc, currentcall);
} else {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot trigger hangup button: Linphone core not ready"];
const MSList* calls = linphone_core_get_calls(lc);
if (ms_list_size(calls) == 1) { // Only one call
linphone_core_terminate_call(lc,(LinphoneCall*)(calls->data));
}
}
}

View file

@ -93,6 +93,19 @@
#pragma mark -
- (NSString *)accessibilityValue {
// TODO: localize?
BOOL incoming = linphone_call_log_get_dir(callLog) == LinphoneCallIncoming;
BOOL missed = linphone_call_log_get_status(callLog) == LinphoneCallMissed;
NSString* call_type = @"Outgoing";
if( incoming ){
call_type = missed?@"Missed" : @"Incoming";
}
return [NSString stringWithFormat:@"%@ from %@", call_type, addressLabel.text];
}
- (void)update {
if(callLog == NULL) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update history cell: null callLog"];

View file

@ -36,7 +36,7 @@
[LinphoneLogger log:LinphoneLoggerWarning format:@"Can't convert not RGB color"];
return self;
} else {
const float *colors = CGColorGetComponents(cgColor);
const CGFloat *colors = CGColorGetComponents(cgColor);
rgbaR = colors[0];
rgbaG = colors[1];
rgbaB = colors[2];
@ -64,7 +64,7 @@
[LinphoneLogger log:LinphoneLoggerWarning format:@"Can't convert not RGB color"];
return self;
} else {
const float *colors = CGColorGetComponents(cgColor);
const CGFloat *colors = CGColorGetComponents(cgColor);
rgbaR = colors[0];
rgbaG = colors[1];
rgbaB = colors[2];

View file

@ -102,6 +102,22 @@ static NSString * const kDisappearAnimation = @"disappear";
object:nil];
}
- (void)flipImageForButton:(UIButton*)button {
UIControlState states[] = { UIControlStateNormal, UIControlStateDisabled, UIControlStateSelected, UIControlStateHighlighted, -1 };
UIControlState *state = states;
while (*state != -1) {
UIImage* bgImage = [button backgroundImageForState:*state];
UIImage* flippedImage = [UIImage imageWithCGImage:bgImage.CGImage
scale:bgImage.scale
orientation:UIImageOrientationUpMirrored];
[button setBackgroundImage:flippedImage forState:*state];
state++;
}
}
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillEnterForeground:)
@ -175,6 +191,14 @@ static NSString * const kDisappearAnimation = @"disappear";
[LinphoneUtils buttonFixStatesForTabs:chatButton];
[LinphoneUtils buttonFixStatesForTabs:chatButtonLandscape];
}
if ([LinphoneManager langageDirectionIsRTL]){
[self flipImageForButton:historyButton];
[self flipImageForButton:settingsButton];
[self flipImageForButton:dialerButton];
[self flipImageForButton:chatButton];
[self flipImageForButton:contactsButton];
}
[super viewDidLoad]; // Have to be after due to TPMultiLayoutViewController
}
@ -201,6 +225,8 @@ static NSString * const kDisappearAnimation = @"disappear";
}
#pragma mark - Event Functions
- (void)applicationWillEnterForeground:(NSNotification*)notif {
@ -250,11 +276,7 @@ static NSString * const kDisappearAnimation = @"disappear";
- (void)update:(BOOL)appear{
[self updateView:[[PhoneMainView instance] firstView]];
if([LinphoneManager isLcReady]) {
[self updateMissedCall:linphone_core_get_missed_calls_count([LinphoneManager getLc]) appear:appear];
} else {
[self updateMissedCall:0 appear:TRUE];
}
[self updateMissedCall:linphone_core_get_missed_calls_count([LinphoneManager getLc]) appear:appear];
[self updateUnreadMessage:appear];
}

View file

@ -24,28 +24,15 @@
@implementation UIMicroButton
- (void)onOn {
if(![LinphoneManager isLcReady]) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle mic button: Linphone core not ready"];
return;
}
linphone_core_mute_mic([LinphoneManager getLc], false);
}
- (void)onOff {
if(![LinphoneManager isLcReady]) {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle mic button: Linphone core not ready"];
return;
}
linphone_core_mute_mic([LinphoneManager getLc], true);
}
- (bool)onUpdate {
if([LinphoneManager isLcReady]) {
return linphone_core_is_mic_muted([LinphoneManager getLc]) == false;
} else {
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update mic button: Linphone core not ready"];
return true;
}
return linphone_core_is_mic_muted([LinphoneManager getLc]) == false;
}
- (void)dealloc {

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